加入3个Oracle表的SQL语句

时间:2012-02-25 07:51:50

标签: sql oracle10g inner-join outer-join

我已经回顾了几个网站和众多教程,试图确定最接近我的情况的匹配,虽然我发现许多类似的可能分辨率,没有确切的解决方案给我我认为我需要的东西。每次尝试我都会返回不正确的数据,重复或无法返回所需的所有字段。非常感谢任何帮助。谢谢,新手

我有三个表,它们各自共享一个SUBR_ID的primary_key。在非专业术语中,我试图从TBL_SUBR_INDV_CARRY_OVER中为所有SUBR_ID和子INDV_ID(一对多)提取BENEFIT_CARRY_OVER,其中GRP_ID ='0G0000000',选择名字,姓氏和订户ID,个人ID和福利结转。下面是引用的三个表,并尝试了语句尝试。

TBL_SUBR_INDV_CARRY_OVER:
SUBR_ID
INDV_ID
BENEFIT_CARRY_OVER

TBL_SUBR_GRP:
SUBR_ID
GRP_ID

TBL_SUBR_INDV:
SUBR_ID
INDV_ID
LNME
FNME

尝试#1

select DISTINCT DCS2000.TBL_SUBR_GRP.SUBR_ID, DCS2000.TBL_SUBR_INDV.INDV_ID, LNME, FNME, GRP_ID, BENEFIT_YEAR, BENEFIT_CARRY_OVER  
from DCS2000.TBL_SUBR_INDV_CARRY_OVER, 
     DCS2000.TBL_SUBR_GRP, 
     DCS2000.TBL_SUBR_INDV
where DCS2000.TBL_SUBR_INDV_CARRY_OVER.SUBR_ID = DCS2000.TBL_SUBR_INDV.SUBR_ID
     and DCS2000.TBL_SUBR_INDV.SUBR_ID = DCS2000.TBL_SUBR_GRP.SUBR_ID
     and DCS2000.TBL_SUBR_GRP.GRP_ID = '0G0000000'
     and DCS2000.TBL_SUBR_INDV_CARRY_OVER.BENEFIT_CARRY_OVER > '0'

尝试#2

select DCS2000.TBL_SUBR_INDV.SUBR_ID, DCS2000.TBL_SUBR_INDV.INDV_ID, DCS2000.TBL_SUBR_INDV.LNME, DCS2000.TBL_SUBR_INDV.FNME, DCS2000.TBL_SUBR_GRP.GRP_ID, DCS2000.TBL_SUBR_INDV_CARRY_OVER.BENEFIT_YEAR, DCS2000.TBL_SUBR_INDV_CARRY_OVER.BENEFIT_CARRY_OVER  
from DCS2000.TBL_SUBR_INDV
join DCS2000.TBL_SUBR_GRP on ( 
     where DCS2000.TBL_SUBR_INDV_CARRY_OVER.SUBR_ID = DCS2000.TBL_SUBR_INDV.SUBR_ID
     and DCS2000.TBL_SUBR_INDV.SUBR_ID = DCS2000.TBL_SUBR_GRP.SUBR_ID
     and DCS2000.TBL_SUBR_GRP.GRP_ID = '0G0000000'
     and DCS2000.TBL_SUBR_INDV_CARRY_OVER.BENEFIT_CARRY_OVER > '0'

尝试3

 SELECT LNME, FNME, SUBR_ID, INDV_ID
 FROM DCS2000.TBL_SUBR_INDV
 WHERE DCS2000.TBL_SUBR_INDV.SUBR_ID IN
        (SELECT BENEFIT_CARRY_OVER
        FROM DCS2000.TBL_SUBR_INDV_CARRY_OVER
        WHERE DCS2000.TBL_SUBR_INDV_CARRY_OVER.SUBR_ID IN
            (SELECT SUBR_ID
            FROM DCS2000.TBL_SUBR_GRP
            WHERE DCS2000.TBL_SUBR_GRP.GRP_ID = '0G0000000')
    )  

2 个答案:

答案 0 :(得分:1)

我认为重复是因为一个人可以拥有许多结转记录。因此,请尝试:

select i.SUBR_ID, 
       i.INDV_ID, 
       max(i.LNME) LNME, 
       max(i.FNME) FNME, 
       max(g.GRP_ID) GRP_ID, 
       o.BENEFIT_YEAR, 
       sum(o.BENEFIT_CARRY_OVER) BENEFIT_CARRY_OVER
from DCS2000.TBL_SUBR_GRP g
join DCS2000.TBL_SUBR_INDV i
  on g.SUBR_ID = i.SUBR_ID
join DCS2000.TBL_SUBR_INDV_CARRY_OVER o
  on i.SUBR_ID = o.SUBR_ID and i.INDV_ID = o.INDV_ID and o.BENEFIT_CARRY_OVER > 0
where g.GRP_ID = '0G0000000' 
group by i.SUBR_ID, 
         i.INDV_ID, 
         o.BENEFIT_YEAR

请注意,订户个人ID需要将单个表连接到结转表;此外,数字字段(例如BENEFIT_CARRY_OVER)不应该在其值周围加上引号。

答案 1 :(得分:0)

问题在于,由于一对多,所有三个表之间的简单连接将为您感兴趣的数据提供重复的行。连接必须为连接在一起的每一行创建一个完整的行。而你想要的只是一行。

我经常发现构建复杂查询最好在部分

中完成

因此,首先要找到所有具有感兴趣值的ID,每个ID都有一行。由于我正在使用的键盘,我会稍微缩短名称。

从subrgrp中选择不同的subr_id,其中grpid = 0000006

然后将其与下一个表格结合起来

从subrindv中选择distinct indvid where subrid in(select subr_id from subrgrp where grpid = 0000006)

然后选择最后感兴趣的行。

从subrindv中选择遗留物,其中是indvid in(从subrindv中选择distinct indvid where subrid in(select subr_id from subrgrp where grpid = 0000006))

另一种方法是使用GROUP BY将多行分组为一个。