PLPGSQL 函数:在 ORDER BY 中使用输入参数

PLPGSQL Function: Use Input Parameter in ORDER BY

我正在尝试在 plpgsql 函数中定义条件 ORDER BY。 像这样:

CREATE OR REPLACE FUNCTION test_function(p_sort_order TEXT, p_limit INTEGER) 
    RETURNS TABLE (
        id TEXT,
        test TEXT
) 
AS $$
BEGIN
    RETURN QUERY SELECT 
                    t.field1 AS id,
                    MIN(t.field2) AS test 
                    FROM table t
                    GROUP BY t.field1
            ORDER BY 
            CASE p_sort_order
                WHEN ‘asc’ THEN test END ASC,
                WHEN ‘desc’ THEN test END DESC
            END
            LIMIT p_limit;
END; $$ 

LANGUAGE 'plpgsql';

这些参数似乎只在 WHERE、LIMIT 等子句中有效,但在 ORDER BY 中无效(尽管我还没有找到任何官方文档)。

实现此目的的解决方法是什么?

根据 link,将您的 select 更改为:

ORDER BY
   CASE WHEN p_sort_order = 'asc' THEN min(t.field2) END ASC,
   CASE WHEN p_sort_order = 'desc' THEN min(t.field2) END DESC
LIMIT p_limit;

这里的神奇之处在于,case 个实例 return 要么是 test 要么是 null,后面跟着的是 ascdesc。如果 p_sort_orderdesc,那么你会得到:

  ORDER BY 
    NULL ASC,
    test DESC

NULL ASC 使所有行在排序规则中相等,因此 order by 落入 test DESC 项。

这对我适用于 PG10(根据您的评论更新):

create or replace function do_sort(p_sort_order text)
  returns table (id int, name text)
as $$
  begin
    return query select users.id, min(users.email)
                   from users
                  group by users.id
                  order by case when p_sort_order = 'asc' then min(users.email) end asc,
                           case when p_sort_order = 'desc' then min(users.email) end desc
                  limit 10;
end; $$ language plpgsql;
CREATE FUNCTION
Time: 10.849 ms

select * from do_sort('desc');

┌───────┬───────────────────────┐
│  id   │         name          │
├───────┼───────────────────────┤
│     9 │ 9user@example.com     │
│    99 │ 99user@example.com    │
│   999 │ 999user@example.com   │
│  9999 │ 9999user@example.com  │
│ 99999 │ 99999user@example.com │
│ 99998 │ 99998user@example.com │
│ 99997 │ 99997user@example.com │
│ 99996 │ 99996user@example.com │
│ 99995 │ 99995user@example.com │
│ 99994 │ 99994user@example.com │
└───────┴───────────────────────┘
(10 rows)

Time: 87.236 ms

select * from do_sort('asc');

┌────────┬────────────────────────┐
│   id   │          name          │
├────────┼────────────────────────┤
│ 100000 │ 100000user@example.com │
│ 100001 │ 100001user@example.com │
│ 100002 │ 100002user@example.com │
│ 100003 │ 100003user@example.com │
│ 100004 │ 100004user@example.com │
│  10000 │ 10000user@example.com  │
│  10001 │ 10001user@example.com  │
│  10002 │ 10002user@example.com  │
│  10003 │ 10003user@example.com  │
│  10004 │ 10004user@example.com  │
└────────┴────────────────────────┘
(10 rows)

Time: 85.219 ms