使用 SELECT CASE 创建函数

Create function with SELECT CASE

我想创建一个有 2 个参数的函数。这是我的 SELECT 声明:

SELECT CASE 
   WHEN duration <=  10000000 THEN '00-01 sec'
           WHEN duration <=  40000000 THEN '01-04 sec' 
           WHEN duration <= 100000000 THEN '04-10 sec' 
           WHEN duration <= 300000000 THEN '10-30 sec' 
           WHEN duration <= 600000000 THEN '30-60 sec' 
           ELSE 'more than 60 sec' END AS "Kategorien", 
   COUNT(*) AS Requestcounter
FROM tablename
WHERE starttime BETWEEN '2016-03-01 00:00:00' AND '2016-03-08 14:00:00'
GROUP BY
  (CASE WHEN duration <=  10000000 THEN '00-01 sec'
   WHEN duration <=  40000000 THEN '01-04 sec' 
   ELSE 'more than 60 sec' END); 

结果:

 Kategorien | requestcounter
------------+----------------
 00-01 sec  |           2073
 01-04 sec  |              2
(2 rows)

我想从我的函数中得到这个结果。但我收到错误:

query has no destination for result data

这是我的功能:

CREATE OR REPLACE FUNCTION requestcounter(mindate timestamptz,maxdate timestamptz) 
RETURNS SETOF integer AS $$ 

BEGIN
SELECT CASE WHEN duration <=  10000000 THEN '00-01 sec'
            WHEN duration <=  40000000 THEN '01-04 sec'  
            ELSE 'more than 60 sec' END AS "Kategorien", 
COUNT(*) AS Requestcounter from tablename where starttime BETWEEN mindate and maxdate
GROUP BY
  (CASE WHEN duration <=  10000000 THEN '00-01 sec' 
        WHEN duration <=  40000000 THEN '01-04 sec'  
        ELSE 'more than 60 sec' END);
Return; 
END;
$$ LANGUAGE plpgsql;

我知道 RETURNS SETOF integer 不对,但我不知道如何让它发挥作用?

我想你想要return一个table,而不是SETOF INTEGER

像这样:

CREATE OR REPLACE FUNCTION requestcounter (mindate timestamptz, maxdate timestamptz) RETURNS TABLE (
    Kategorien text,
    requestcounter int
) AS
$BODY$
BEGIN
    RETURN QUERY
    SELECT CASE WHEN duration <=  10000000 THEN '00-01 sec'
                WHEN duration <=  40000000 THEN '01-04 sec'  
                ELSE 'more than 60 sec' END AS "Kategorien", 
    COUNT(*) AS Requestcounter from tablename where starttime BETWEEN mindate and maxdate GROUP BY
    (CASE WHEN duration <=  10000000 THEN '00-01 sec' 
    WHEN duration <=  40000000 THEN '01-04 sec'  
    ELSE 'more than 60 sec' END);
END
$BODY$
LANGUAGE 'plpgsql';

我认为您编写的函数是 运行 一个 select 无处发送输出的查询,然后是 return 一组空整数。 (这就是您收到该错误的原因。)

already provided that you need RETURN QUERY to actually return the results of a query from a plpgsql function.

但是对于一个简单的 SELECT,您不需要 plpgsql。使用像@Travis 还提供的 plain SQL function instead. You need to define the return type either way, best use RETURNS TABLE,但实际 returned 的数据类型必须精确匹配:

CREATE OR REPLACE FUNCTION requestcounter(_mindate timestamptz, _maxdate timestamptz) 
  RETURNS TABLE (kategorien text, requestcounter int) AS
$func$ 
SELECT CASE WHEN duration <= 10000000 THEN '00-01 sec'::text
            WHEN duration <= 40000000 THEN '01-04 sec'
            -- more cases ...
            ELSE 'more than 60 sec' END  -- AS kategorien -- not visible outside function
     , count(*)::int                     -- AS requestcounter
FROM   tablename
WHERE  starttime BETWEEN _mindate AND _maxdate
GROUP  BY 1                              -- simpler with positional reference
ORDER  BY 1                              -- see below   
$func$  LANGUAGE sql;                    -- never quote the language name
  • count()returns bigint。如果将 returned 列 requestcounter 定义为 int,则必须强制转换:count(*)::int(或以 return bigint 开头。)

  • 在 SQL 函数中,您可以使用普通的 SELECT 到 return 行。

  • 避免参数和列名之间的命名冲突。一个常见的约定是像我一样为参数添加前缀。

  • GROUP BY 中的位置引用是 SELECT 列表中长表达式的一种非常方便的语法快捷方式。这也确保 GROUP BY 项匹配 SELECT 项(在您的第一个查询中 不是 的情况)。

  • 您可能想要添加 ORDER BY 1,否则您会得到任意顺序。您演示的 text 发生 以正确的顺序排序。

致电:

SELECT * FROM requestcounter('2015-01-01 00:00+01', '2015-03-01 00:00+01')