Sql 使用Listagg时数据重复

Sql 使用Listagg时数据重复,sql,oracle,Sql,Oracle,我已经在这个问题上尝试了很多个小时,我的数据(手头数字,PO)一直显示重复数据,请参考我的代码如下。顺便说一句,如果我删除了下面的代码,那么我现有的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 b

我已经在这个问题上尝试了很多个小时,我的数据(手头数字,PO)一直显示重复数据,请参考我的代码如下。顺便说一句,如果我删除了下面的代码,那么我现有的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

不幸的是,
listagg()
不支持
distinct
选项。您可以使用窗口函数或通过沿每个维度预聚合来解决此问题。后一种方法效率更高,但如果没有样本数据,我不太愿意提出具体的查询

因此,一个非常简单的方法是使用
row\u 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\u REF
包括在
选择中。在按该列进行聚合时,这似乎是一个很好的做法。当然,你不需要包括它


我还更改了列别名,因此它们不需要转义字符(双引号)。必须转义标识符只会使查询更难编写和读取。

您需要向我们展示一些示例数据,并使其成为一个最小且可重复的问题。@TimBiegeleisen您好,我已编辑了我的问题,以使其更简单。“如果我删除以下代码,我的数据看起来就不会重复。”>>>因此将其删除。问题是表
EXPORT\u SHPMNT\u CTNR
中的列
SHPMNT\u REF
不是唯一的,因此联接会将结果相乘。检查为什么要执行联接,因为查询中没有使用该表。@Littlefoot我需要它来从中获取数据。谢谢您的回复,但我在使用代码时收到一个错误。“OH.ONHAND_REF”在使用它的上下文中无效。.SQLCODE=-206,SQLSTATE=42703,DRIVER=4.19.49.2)[Code:-727,SQL State:56098]在隐式系统操作类型“2”期间发生错误。“如果可能,请提供帮助,非常感谢。@CKAng。对这些别名仅在子查询中已知。我修正了密码。