Выбор структуры управления 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 заявление для последнего столбца, хотя...

Другие вопросы по тегам