从LEFT OUTER JOIN中删除重复项

时间:2010-03-28 14:54:16

标签: sql oracle oracle10g left-join outer-join

我的问题与Restricting a LEFT JOIN非常相似,但有一个变体。

假设我有一个表SHOP和另一个表LOCATION。表位是表SHOP的一种子表,它有两列感兴趣的,一个是分区键(称之为KEY)和一个“SHOP”号。这与表SHOP中的数字“NO”匹配。

我试过这个左外连接:

SELECT S.NO, L.KEY
FROM SHOP S
LEFT OUTER JOIN LOCATN L ON S.NO = L.SHOP

但是由于有很多地方属于一家商店,所以我得到了很多重复。我想消除它们,只是得到一个没有重复的“商店,关键”条目列表。

数据正确但重复显示如下:

SHOP     KEY
 1       XXX
 1       XXX
 2       YYY
 3       ZZZ
 3       ZZZ  etc.

我希望数据显示为:

SHOP     KEY
 1       XXX
 2       YYY
 3       ZZZ  etc.

SHOP表:

 NO
 1       
 2       
 3       

位置表:

 LOCATION   SHOP  KEY
   L-1       1    XXX   
   L-2       1    XXX   
   L-3       2    YYY   
   L-4       3    YYY   
   L-5       3    YYY   

(ORACLE 10g数据库)

3 个答案:

答案 0 :(得分:25)

你需要GROUP BY'S.No'& 'L.KEY'

SELECT S.NO, L.KEY 
FROM SHOP S 
LEFT OUTER JOIN LOCATN L 
ON S.NO = L.SHOP
GROUP BY S.NO, L.KEY

答案 1 :(得分:7)

编辑在您的方案中进行更新

我认为你应该能够通过一个简单的子查询来做到这一点(尽管我还没有针对Oracle数据库进行测试)。类似于以下内容

UPDATE shop s
SET divnkey = (SELECT DISTINCT L.KEY FROM LOCATN L WHERE S.NO = L.SHOP)

如果商店与多个部门的位置相关联,上述情况将引发错误。

如果您只是想忽略这种可能性并在该事件中选择任意一种,您可以使用

UPDATE shop s
SET divnkey = (SELECT MAX(L.KEY) FROM LOCATN L WHERE S.NO = L.SHOP)

答案 2 :(得分:6)

我也有这个问题,但是我无法使用GROUP BY来修复它,因为我还返回了TEXT类型的字段。 (使用DISTINCT也一样)。

这段代码给了我重复:

select mx.*, case isnull(ty.ty_id,0) when 0 then 'N' else 'Y' end as inuse 
from master_x mx 
left outer join thing_y ty on mx.rpt_id = ty.rpt_id

我通过改写它来修复它:

select mx.*, 
case when exists (select 1 from thing_y ty where mx.rpt_id = ty.rpt_id) then 'Y' else 'N' end as inuse
from master_x mx 

正如您所看到的,我并不关心第二个表(thing_y)中的数据,只知道其中的rpt_id是否存在大于零的匹配。 (仅供参考:rpt_id也不是第一张桌子上的主键master_x)。