用于在查询Postgresql中标记重复项的函数

用于在查询Postgresql中标记重复项的函数,postgresql,function,duplicates,arguments,Postgresql,Function,Duplicates,Arguments,我想编写一个函数,在postgresql中标记指定列中的重复项 例如,如果我有下表: country | landscape | household -------------------------------- TZA | L01 | HH02 TZA | L01 | HH03 KEN | L02 | HH01 RWA | L03 | HH01 我希望能够运行以下查询: SELECT country,

我想编写一个函数,在postgresql中标记指定列中的重复项

例如,如果我有下表:

country | landscape | household
--------------------------------
TZA     | L01       | HH02
TZA     | L01       | HH03
KEN     | L02       | HH01
RWA     | L03       | HH01
我希望能够运行以下查询:

SELECT country,
       landscape,
       household,
       flag_duplicates(country, landscape) AS flag
FROM mytable
并得到如下结果:

country | landscape | household | flag
---------------------------------------
TZA     | L01       | HH02      | duplicated
TZA     | L01       | HH03      | duplicated
KEN     | L02       | HH01      |
RWA     | L03       | HH01      |
在函数体中,我想我需要如下内容:

IF (country || landscape IN (SELECT country || landscape FROM mytable
                            GROUP BY country || landscape)
    HAVING count(*) > 1) THEN 'duplicated'
ELSE NULL

但我对如何将所有这些作为论点进行传递感到困惑。我感谢你的帮助。我使用的是postgresql 9.3版。

您不需要函数来实现这一点。由于性能原因,对结果集中的每一行使用函数并不是一个好主意。一种更好的解决方案是使用纯SQL(甚至包括子查询),并给数据库引擎优化它的机会。在您的示例中,应该是这样的:

SELECT t.country,t.landscape,t.household,case when duplicates.count>1 then 'duplicate'end 
FROM mytable t JOIN ( 
SELECT count(household) FROM mytable GROUP BY country,landscape
) duplicates ON duplicates.country=t.country AND duplicates.landscape=t.landscape
这会产生完全相同的结果

更新-如果您想不惜一切代价使用函数,下面是一个工作示例:

CREATE FUNCTION find_duplicates(arg_country varchar, arg_landscape varchar) returns varchar AS $$
BEGIN
    RETURN CASE WHEN count(household)>1 THEN 'duplicated' END FROM mytable
    WHERE country=arg_country AND landscape=arg_landscape
    GROUP BY country,landscape;
END
$$
LANGUAGE plpgsql STABLE;

你不需要一个函数来完成它。由于性能原因,对结果集中的每一行使用函数并不是一个好主意。一种更好的解决方案是使用纯SQL(甚至包括子查询),并给数据库引擎优化它的机会。在您的示例中,应该是这样的:

SELECT t.country,t.landscape,t.household,case when duplicates.count>1 then 'duplicate'end 
FROM mytable t JOIN ( 
SELECT count(household) FROM mytable GROUP BY country,landscape
) duplicates ON duplicates.country=t.country AND duplicates.landscape=t.landscape
这会产生完全相同的结果

更新-如果您想不惜一切代价使用函数,下面是一个工作示例:

CREATE FUNCTION find_duplicates(arg_country varchar, arg_landscape varchar) returns varchar AS $$
BEGIN
    RETURN CASE WHEN count(household)>1 THEN 'duplicated' END FROM mytable
    WHERE country=arg_country AND landscape=arg_landscape
    GROUP BY country,landscape;
END
$$
LANGUAGE plpgsql STABLE;
对于函数,请查看,但添加到函数的定义中以加快其调用

对于函数,请查看,但添加到函数的定义中以加快其调用