我有以下两种情况和所需的输出。不确定是否可以使用LISTAGG或PIVOT。
需要有关编写SQL查询以实现所需输出的最佳方法的帮助。
这是我到目前为止尝试过的。但是,我没有考虑过AUTH。我正在考虑考虑AUTH的查询,如果添加了更多列,则应该可以扩展。
SELECT CLM_TYPE_CSV,
LISTAGG (PROGRAM, ',') WITHIN GROUP (ORDER BY PROGRAM)
AS PROGRAM_CSV
FROM ( SELECT PROGRAM,
LISTAGG (CLAIM_TYPE, ',') WITHIN GROUP (ORDER BY CLAIM_TYPE)
AS CLM_TYPE_CSV
FROM STG_EDIT_DISP_PARAM
WHERE ERR_NUM = '001'
GROUP BY PROGRAM)
GROUP BY CLM_TYPE_CSV
不胜感激! -#### SCENARIO 1 ############
---------------------------------------------------------
ERR_NUM | PROGRAM | CLAIM_TYPE | AUTH |
---------------------------------------------------------
001 | BLG | P | Y
001 | ENG | O | Y
001 | ENG | P | Y
001 | FED | O | Y
001 | FED | P | Y
001 | FED | Q | Y
所需的输出:
--------------------------------------------------------
ERR_NUM | PROGRAM | CLAIM_TYPE | AUTH |
--------------------------------------------------------
001 | BLG | P | Y
001 | ENG,FED | O,P | Y
001 | FED | Q | Y
-#### SCENARIO 2 ############ --------------------------- -
---------------------------------------------------------
ERR_NUM | PROGRAM | CLAIM_TYPE | AUTH |
---------------------------------------------------------
001 | BLG | P | N
001 | ENG | O | Y
001 | ENG | P | N
001 | FED | O | Y
001 | FED | P | Y
001 | FED | Q | Y
001 | FED | X | N
所需的输出:
--------------------------------------------------------------------
ERR_NUM | PROGRAM | CLAIM_TYPE | AUTH |
------------------------------------------------------------------
001 | BLG,ENG | P | N
001 | ENG,FED | O | Y
001 | FED | P,Q | Y
001 | FED | X | N
答案 0 :(得分:1)
让我为第一种情况提供指导(并希望您为第二种情况学习)。
首先,您需要 LISTAGG ,但不需要 PIVOT 。
当您关注列program
和claim_type
时,请按照以下解决方案(通过使用having(count(...))
结构)分别考虑重复值和非重复值:
select err_num,
listagg(program,',') within group (order by program) as program,
max(claim_type) as claim_type,
auth
from
(
select err_num,program,
min(claim_type)||','||max(claim_type) as claim_type,
auth
from tab
where claim_type in
(
select claim_type
from tab
group by claim_type
having count(claim_type)>1
)
group by program, err_num, auth
having count(program)>1
)
group by claim_type, err_num, auth
union all
select err_num, program, claim_type, auth
from tab
where program in
(
select program
from tab
group by program
having count(program)=1
)
union all
select err_num, program, claim_type, auth
from tab
where claim_type in
(
select claim_type
from tab
group by claim_type
having count(claim_type)=1
)
order by program, claim_type;
答案 1 :(得分:0)
因此,您要:
如果是,则可以使用分析功能来计算每个err_num,auth和Claim_type的程序计数。在您的最终分组依据中添加此计数。
要使listagg返回不同的值,如果程序和Claim_type不是当前组中的第一个,则将其映射为null。您可以通过将值传递给row_number,并在此值为1时返回该列来完成此操作。否则为null。
哪个给:
create table tab (
err_num varchar2(3), program varchar2(3),
claim_type varchar2(3), auth varchar2(3)
);
insert all
into tab values ('001','BLG','P','N')
into tab values ('001','ENG','O','Y')
into tab values ('001','ENG','P','N')
into tab values ('001','FED','O','Y')
into tab values ('001','FED','P','Y')
into tab values ('001','FED','Q','Y')
into tab values ('001','FED','X','N')
select * from dual;
with rws as (
select t.*, row_number () over ( order by err_num, program, claim_type ) rn,
count (*) over ( partition by err_num, claim_type, auth ) grp_count
from tab t
), grps as (
select r.*,
case
when row_number () over ( partition by claim_type, auth, grp_count order by 1 ) = 1 then
claim_type
end claim_first,
case
when row_number () over ( partition by program, auth, grp_count order by 1 ) = 1 then
program
end prog_first
from rws r
)
select err_num,
listagg ( prog_first, ',' ) within group ( order by rn ) progs,
listagg ( claim_first, ',' ) within group ( order by rn ) claims,
auth
from grps
group by err_num, auth, grp_count;
ERR_NUM PROGS CLAIMS AUTH
001 FED X N
001 BLG,ENG P N
001 FED P,Q Y
001 ENG,FED O Y
洛朗·施耐德(Laurent Schneider)提出了许多独特的listaggs方法https://laurentschneider.com/wordpress/2014/05/distinct-listagg.html