按外键分组并获得新行

时间:2017-01-16 10:32:45

标签: sql oracle having listagg

我需要计算表人员中的所有外键,如果外键被引用超过一次,则列出person_id。如果我在一个单元格中列出所有person_id,这并不复杂。

例如,如果我有这张表:

    PERSON_ID | FOREIGN_KEY
    1           a0368dwas
    2           b65asd14s 
    3           b65asd14s 
    4           a0368dwas
    5           cd56as46a

我可以做这个SQL查询:

    select listagg(person_id), ', '), foreign_key
    from person
    group by foreign_key
    having count(foreign_key)>1
    order by foreign_key

结果如下:

    PERSON_ID | FOREIGN_KEY
    1,4         z0368dwas
    2,3         z65asd14s 

我的问题是用户要求,因为他需要person_id不在一行中,而是每行person_id一行。

所以它必须是这样的:

    PERSON_ID | FOREIGN_KEY
    1           a0368dwas
    4           a0368dwas
    2           b65asd14s 
    3           b65asd14s 

2 个答案:

答案 0 :(得分:3)

这就是分析函数(它们类似于聚合函数,除了它们不会将行折叠成单行)的地方,特别是COUNT(*) OVER ()解析函数:

select person,
       foreign_key
from   (select person,
               foreign_key,
               count(*) over (partition by foreign_key) fk_cnt
        from   person)
where  fk_cnt > 1;

这里,“partition by”子句取代了聚合查询中的“group by”子句 - 它定义了解析函数将要处理的行集。您必须在子查询中执行分析函数,然后在外部查询中过滤结果,因为还没有等效的分析函数的“having”子句。

答案 1 :(得分:0)

选择person,foreign_key 来自( 从中选择foreign_key(选择foreign_key,count(1) 从人 由foreign_key分组 有计数(1)> 1) ) 按2排序