简体   繁体   English

Oracle LISTAGG DISTINCT 与多个条件

[英]Oracle LISTAGG DISTINCT with multiple conditions

For Oracle12, I have the table shown below对于 Oracle12,我有如下所示的表格

ID ID CONTACTCODE联系代码 CONTACTPERSON联系人
1 1 X X CLIENT客户
1 1 X X CLIENT客户
1 1 X X WIFE妻子
1 1 Y CLIENT客户
1 1 Z Z WIFE妻子
1 1 Z Z CLIENT客户
1 1 Z Z HUSBAND丈夫
1 1 W W CLIENT客户
2 2 Y CHILD孩子
2 2 Y WIFE妻子
2 2 Y CLIENT客户
3 3 Y HUSBAND丈夫
3 3 W W CLIENT客户

And I want the result like:我想要这样的结果:

  • CONTACTPERSON is CLIENT.联系人是客户。 If CONTACTCODE in (X,Y,Z) then list all distinct CONTACTCODE ( Ex: X,Y,...) else 0 ( MAIN column)如果 CONTACTCODE 在 (X,Y,Z) 然后列出所有不同的 CONTACTCODE ( 例如: X,Y,...) else 0 ( MAIN 列)
  • CONTACTPERSON <> CLIENT.联系人 <> 客户。 If CONTACTCODE in (X,Y,Z) then list all distinct CONTACTCODE ( Ex: X,Y,...) else 0 ( REF column)如果 CONTACTCODE 在 (X,Y,Z) 中,则列出所有不同的 CONTACTCODE(例如:X,Y,...)否则 0(REF 列)

Expected table:预期表:

ID ID MAIN主要的 REF参考
1 1 X,Y, Z X,Y,Z X,Z X,Z
2 2 Y Y
3 3 0 0 Y

I used row_number partition by ID, CONTACTCODE and then LISTAGG where row_number = 1 but I had many problems.我使用按 ID、CONTACTCODE 和 LISTAGG 的 row_number 分区,其中 row_number = 1 但我遇到了很多问题。

You can use the distinct , case..when and LISTAGG as follows:您可以使用distinctcase..whenLISTAGG ,如下所示:

select id, 
       coalesce(listagg(case when isclient = 'CLIENT' then contactcode end,',') 
                  within group (order by contactcode), '0') as maincode,
       coalesce(listagg(case when isclient = 'NOT CLIENT' then contactcode end,',') 
                  within group (order by contactcode), '0') as ref 
(select distinct id, contactcode, 
        case when contactperson = 'CLIENT' then 'CLIENT' else 'NOT CLIENT' end as isclient
  from your_table t
 where t.contactcode in ('X', 'Y', 'Z') ) t
 group by id

You can use row_number() and conditional aggregation:您可以使用row_number()和条件聚合:

select id,
       (case when sum(case when contactperson = 'Client' then 1 else 0 end) > 0
             then listagg(case when seqnum = 1 and contactcode in ('X', 'Y', 'Z')
                               then contactcode
                          end, '') within group (order by contactcode)
        end),
       listagg(case when seqnum = 1 and contactcode in ('X', 'Y', 'Z')
                    then contactcode
               end, '') within group (order by contactcode)
from (select t.*,
             row_number() over (partition by id, contactcode order by id) as seqnum
      from t
     ) t
group by id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM