我已经在这个问题上尝试了许多小时,我的数据(ONHAND NUM,PO)一直显示重复的数据,请参考下面的代码。顺便说一句,如果我删除下面的代码,那么我的ONHAND NUM&PO将不再重复,因此我认为这些代码有问题。请协助。谢谢。
select
listagg(OH.ONHAND_REF,', ')within group(order by ES.SHPMNT_REF) as "Onhand Num",
listagg(PO.PO_ALL_TRACES,', ')within group(order by PO.PO_ALL_TRACES) as "PO"
from BRDB.EXPORT_SHIPMENT ES
left outer join EXPORT_ONHAND OH on ES.SHPMNT_REF = OH.SHPMNT_REF
left outer join VW_EXPORT_TRACE_PO PO on PO.FILE_NO = OH.ONHAND_REF
left outer join EXPORT_SHPMNT_CTNR CTNR on CTNR.SHPMNT_REF = ES.SHPMNT_REF
group by ES.SHPMNT_REF
如果我删除以下代码,则我的数据看起来将没有重复
left outer join BRDB.EXPORT_SHPMNT_CTNR CTNR on CTNR.SHPMNT_REF = ES.SHPMNT_REF
我收到的结果如下
Onhand Num PO
555,555,555 P0001,P0001,P0001
666,777,666,777 P0002,P0003,P0002,P0003
我想要的结果
Onhand Num PO
555 P0001
666,777 P0002,P0003
答案 0 :(得分:1)
很遗憾,listagg()
不支持distinct
选项。您可以使用窗口函数或通过沿每个维度进行预聚合来解决此问题。后一种方法效率更高,但是由于没有示例数据,我不愿提出一个具体的查询。
因此,一种足够简单的方法是使用row_number()
和listagg()
忽略NULL
值的事实:
select x.SHPMNT_REF,
listagg(case when seqnum_ohr = 1 then x.ONHAND_REF end, ', '
) within group (order by x.SHPMNT_REF) as onhand_numbers,
listagg(case when seqnum_pat = 1 then x.PO_ALL_TRACES end, ', '
) within group (order by x.PO_ALL_TRACES) as pos
from (select ES.SHPMNT_REF, PO.PO_ALL_TRACES, OH.ONHAND_REF,
row_number() over (partition by ES.SHPMNT_REF, PO.PO_ALL_TRACES order by ES.SHPMNT_REF) as seqnum_pat,
row_number() over (partition by ES.SHPMNT_REF, OH.ONHAND_REF order by ES.SHPMNT_REF) as seqnum_ohr
from BRDB.EXPORT_SHIPMENT ES left outer join
EXPORT_ONHAND OH
on ES.SHPMNT_REF = OH.SHPMNT_REF left outer join
VW_EXPORT_TRACE_PO PO
on PO.FILE_NO = OH.ONHAND_REF left outer join
EXPORT_SHPMNT_CTNR CTNR
on CTNR.SHPMNT_REF = ES.SHPMNT_REF
) x
group by x.SHPMNT_REF;
请注意,我还将SHPMNT_REF
包括在SELECT
中。按该列进行汇总时,这似乎是一种好习惯。当然,您不需要包含它。
我还更改了列别名,因此它们不需要转义符(双引号)。必须转义标识符只会使查询难以编写和阅读。