在Postgresql中创建一个多列作为参数的函数

我正在尝试创建一个函数,该函数将一个表和一个可变数量的列作为参数,然后返回一个没有行的表,这些行在所有这些列上都有重复项.我试图弄清楚如何将可变数量的列作为参数,我已经收集到我可能需要一个VARIADIC参数,但我不知道如何实现它.到目前为止我所拥有的:

CREATE FUNCTION remove_duplicates(orig_table, VARIADIC sel_columns column)
RETURNS table AS $$
    SELECT * FROM 
        (SELECT *,
            count(*) over (partition by sel_columns) AS count
        FROM orig_table)
    WHERE count = 1;
$$LANGUAGE SQL;

举个例子,如果我有一个这样的表:

cola | colb | colc
-------------------
a    | b    | 1
a    | b    | 2
a    | c    | 3
a    | d    | 4

我想运行SELECT * FROM remove_duplicates(mytable,cola,colb)并得到这个结果:

cola | colb | colc
-------------------
a    | c    | 3
a    | d    | 4

感谢您的帮助.我正在使用postgresql 9.4.9

最佳答案 使用简单的SQL函数无法获得所需的功能,您需要使用过程语言的强大功能.可能的解决方案是:

CREATE OR REPLACE FUNCTION remove_duplicates(orig_table anyelement, VARIADIC sel_columns text[])
RETURNS SETOF anyelement AS $$
DECLARE
    orig_table_columns TEXT;
BEGIN
    SELECT array_to_string(array_agg(quote_ident(column_name)),',') INTO orig_table_columns FROM information_schema.columns WHERE table_name = CAST(pg_typeof(orig_table) AS TEXT);
    RETURN QUERY EXECUTE 'SELECT ' || orig_table_columns || ' FROM '
        || '(SELECT *, '
        || '    count(*) over (partition by ' || array_to_string(sel_columns, ',') || ') AS count '
        || 'FROM ' || pg_typeof(orig_table) || ') AS tmp '
        || ' WHERE count = 1 ';
END
$$LANGUAGE PLPGSQL;

SELECT * FROM remove_duplicates(NULL::tests, 'cola', 'colb');

不要忘记进行更改以避免SQL注入.

编辑:有关动态返回类型函数的非常好的解释,请参阅Erwin的答案here.

点赞