连接表时重复的行

时间:2018-08-03 14:29:05

标签: sql oracle

我在使用SQL时遇到麻烦。我的问题是我得到很多重复的行,但是我不知道如何解决它。

我有下表:

tblCGG,其列为:listIddescription

tblCLA的列:listidCLADescription

tblHEA,其列为:listidHEADescription

tblACT,其列为:listidACTDescription

如果我用listid = '132623'分别运行这些表,则会得到以下输出:

tblCGG: 1 row

tblCLA: 4 rows

tblHEA: 10 rows

tblACT: 4 rows

我想将这些表连接在一起,但是我可以通往很多行。

我在下面尝试了此查询,但得到160行:

select distinct cgg.listid, cla.claDescription, hea.heaDescription, 
act.actDescription
from tblCGG cgg
left join tblCLA cla on cgg.listid = cla.listid
left join tblHEA hea on cgg.listid = hea.listid
left join tblACT act on cgg.listid = act .listid
where cgg.listid = '132623'

所需的输出

listid    claDescription   heaDescription            actDescription
132623          claTest        hea1                      act1
132623          clads          hea2                      act2
132623          cloas          hea3                      act3
132623          ccaa           hea4                      act4
132623          null           hea5                      null
132623          null           hea6                      null
132623          null           hea7                      null
132623          null           hea8                      null
132623          null           hea9                      null
132623          null           hea10                     null

3 个答案:

答案 0 :(得分:1)

我不确定所需的输出是否真的有意义。但是,如果这是您的真正需求,那么真的需要。

select coalesce(t.listid, c.listid, a.listid, h.listid) listid, 
       cladescription, headescription, actdescription
  from tblcgg t
  FULL OUTER join (select a.*, row_number() over(partition by listid order by cladescription) seq_no from tblcla a) c on t.listid=c.listid
  FULL OUTER join (select a.*, row_number() over(partition by listid order by actdescription) seq_no from tblact a) a on t.listid=a.listid and a.seq_no=c.seq_no
  FULL OUTER join (select a.*, row_number() over(partition by listid order by headescription) seq_no from tblhea a) h on h.listid=a.listid and (h.seq_no=c.seq_no or h.seq_no=a.seq_no) 
 where coalesce(t.listid, c.listid, a.listid, h.listid)=132623

我对这段代码有点不高兴,因为在较大的数据集上性能会很低,但是如果不编写函数就无法快速找到更好的解决方案。 很少的代码说明:

  • row_number()是用于获取每个表中每个描述的序列号的窗口函数(您可以在其中使用“ order by”进行所需的排序)
  • 完全不应该使用完全外部联接,因为性能不是它的好方面,但是您想要一个相当奇怪的输出,因此对它有好处
  • coalesce()返回第一个非空值

您真的应该考虑是否将所有描述结合起来对您来说不会更好:

select listid, 'cgg' source,description from tblcgg where listid=132623
UNION ALL
select listid, 'act' source,actdescription from tblact where listid=132623
UNION ALL
select listid, 'head' source,headescription from tblhea where listid=132623
UNION ALL
select listid, 'cla' source,cladescription from tblcla where listid=132623

答案 1 :(得分:0)

您希望在每列中有一个单独的列表。这并不是SQL真正要做的事情,但是您可以安排它。一种方法使用row_number()group by

select listid, max(claDescription) as claDescription,
       max(heaDescription) as heaDescription,
       max(actDescription) as actDescription
from ((select cla.listid, cla.claDescription, NULL as heaDescription, NULL as actDescription,
              row_number() over (partition by cla.listid order by cla.listid) as seqnum
       from tblCLA cla
      ) union all
      (select hea.listid, NULL as claDescription, hea.heaDescription, NULL as actDescription,
              row_number() over (partition by hea.listid order by hea.listid) as seqnum
       from tblHEA hea
      ) union all
      (select act.listid, NULL as claDescription, NULL as heaDescription, act.actDescription,
              row_number() over (partition by act.listid order by act.listid) as seqnum
       from tblACT act
      )
     ) x
where listid = 132623  -- only use single quotes if this is really a string
group by listid, seqnum;

答案 2 :(得分:0)

以下查询将提供您想要的结果。这是原始版本的略微修改,但取决于知道WITH ctecla as (select listid, cladescription, rownum as cla_rownum from tblcla), ctehea as (select listid, headescription, rownum as hea_rownum from tblhea), cteact as (select listid, actdescription, rownum as act_rownum from tblact) select cgg.listid, cla.claDescription, hea.heaDescription, act.actDescription from tblCGG cgg left join cteHEA hea on hea.listid = cgg.listid left join cteCLA cla on cla.listid = hea.listid AND cla.cla_rownum = hea.hea_rownum left join cteACT act on act.listid = hea.listid AND act.act_rownum = hea.hea_rownum where cgg.listid = '132623'; 中的行最多:

{{1}}

SQLFiddle here