21

我的问题与Restricting a LEFT JOIN非常相似,但有所不同。

假设我有一个表 SHOP 和另一个表 LOCATION。Location 是表 SHOP 的一种子表,它有两列感兴趣,一个是 Division Key(简称为 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.

店铺表:

 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 数据库)

4

3 回答 3

29

你需要 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
于 2010-03-28T14:59:26.463 回答
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)
于 2010-03-28T14:58:39.557 回答
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)。

于 2012-12-11T17:16:21.183 回答