【问题标题】:Postgres IF control structure selectPostgres IF 控制结构选择
【发布时间】:2014-03-13 21:08:39
【问题描述】:

这是场景。我想根据记录数返回一个 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$

请注意,语法是近似的,但意图应该很明显。如果记录集很小,则返回查询,否则返回 ntiled 查询。尝试执行此操作时,我收到了各种错误消息,包括:

不能在非 SETOF 函数中使用 RETURN QUERY

或

查询没有结果数据的目的地

另外,我知道您不应该在生产代码中使用 *。

【问题讨论】:

    标签: sql postgresql plpgsql window-functions


    【解决方案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 语句替换,不过 ...

    【讨论】:

      猜你喜欢
      • 2013-12-31
      • 1970-01-01
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多