Выбор структуры управления Postgres IF
Вот сценарий. Я хотел бы вернуть ntiled набор результатов в зависимости от количества записей. Например:
DO
$BODY$
IF ( SELECT count(*) < 50 FROM (
SELECT * FROM ( SELECT col1, col2, col3 FROM v_my_view) AS cnt; )
THEN
SELECT * FROM ( SELECT col1, col2, col3 FROM v_my_view ) AS qry;
ELSE (
SELECT *, NTILE(5) OVER (ORDER BY col1 DESC) AS my_tile FROM (
SELECT col1, col2, col3 FROM v_my_view ) AS tileme; )
END IF;
END;
$BODY$
Обратите внимание, синтаксис приблизительный, но намерение должно быть очевидным. Если набор записей невелик, верните запрос, иначе вернитесь к нулевому запросу. У меня были различные сообщения об ошибках, пытаясь выполнить это, в том числе:
нельзя использовать RETURN QUERY в функции без SETOF
или же
у запроса нет места назначения для данных результата
Кроме того, я знаю, что вы не должны использовать * в рабочем коде.
1 ответ
Проблема в том, что вы не можете вернуть строки из DO
заявление на всех. Вам нужно использовать функцию с объявленным RETURN
тип. Чтобы разрешить процедурные элементы, используйте LANGUAGE plpgsql
(который также используется по умолчанию для DO
заявления):
CREATE OR REPLACE FUNCTION foo()
RETURNS TABLE(col1 text, col2 text, col3 text, my_tile int) AS
$func$
BEGIN
IF (SELECT count(*) < 50 FROM v_my_view) THEN
RETURN QUERY
SELECT v.col1, v.col2, v.col3, 0 AS my_tile
FROM v_my_view v;
ELSE
RETURN QUERY
SELECT v.col1, v.col2, v.col3, ntile(5) OVER (ORDER BY v.col1 DESC)
FROM v_my_view v;
END IF;
END
$func$ LANGUAGE sql STABLE;
Типы данных в RETURNS
предложение должно соответствовать вашим фактическим типам данных. Псевдонимы столбцов внутри запроса не видны в результате. Вместо этого объявленные имена в RETURNS
пункт используются.
Также, count(*)
прекрасно синтаксис.
Это можно заменить простым запросом и CASE
заявление для последнего столбца, хотя...