SQL自我加入挑战

时间:2013-05-16 18:39:14

标签: sql sql-server-2008 tsql

我有一张这样的表:

ManufacturerID   ProductID     Price    Region
==============================================
100              1             12.00    A
100              2             20.00    A
100              3             25.00    A
100              4             30.00    B
101              1             15.00    A
101              2             20.00    A
101              4             30.00    B

我想获得一个查询结果,比较两个不同的制造商,如下所示:

ProductID     Price1    Price2    Region
=========================================================================
1             12.00     15.00     A
2             20.00     20.00     A
3             25.00     null      A
4             30.00     30.00     B

我尝试在同一张桌子上使用左连接:

SELECT ProductID, a.Price AS Price1, b.Price AS Price2, a.Region
FROM   table1 a 
       LEFT JOIN table1 b ON a.ProductID = b.ProductID AND a.ManufacturerID = 100
WHERE  b.ManufacturerID = 101

但是这并没有给我制造商101中缺少的产品(ID:4)。我缺少什么?

3 个答案:

答案 0 :(得分:3)

a.ManufacturerIDb.ManufacturerID条款中的onwhere方向错误 - 请尝试:

SELECT ProductID, a.Price AS Price1, b.Price AS Price2, a.Region
FROM   table1 a 
       LEFT JOIN table1 b ON a.ProductID = b.ProductID AND b.ManufacturerID = 101
WHERE  a.ManufacturerID = 100

答案 1 :(得分:2)

我会使用聚合而不是连接来执行此操作:

select ProductId,
       MAX(case when ManufacturerId = 100 then Price end) as Price1,
       MAX(case when ManufacturerId = 101 then Price end) as Price2,
       Region
from table1
where ManufacturerId in (100, 101)
group by ProductId, Region;

答案 2 :(得分:1)

由于您无法提前知道哪些产品会丢失,例如制造商A可能缺少产品3而制造B缺少产品8,您需要FULL OUTER加入,如果您想要这样做加入(戈登提供了另一种方式)。

我认为(ManufacturerID ,ProductID, Region)组合有UNIQUE约束:

SELECT COALESCE(a.ProductID, b.ProductID) AS ProductID, 
       a.Price AS Price1, 
       b.Price AS Price2, 
       COALESCE(a.Region, b.Region) AS Region
FROM   
       ( SELECT ProductID, Price, Region
         FROM table1
         WHERE ManufacturerID = 100
       ) AS a
    FULL JOIN 
       ( SELECT ProductID, Price, Region
         FROM table1
         WHERE ManufacturerID = 101
       ) AS b
           ON  a.ProductID = b.ProductID 
           AND a.Region = b.Region      -- not sure if you need this line
;

SQL-Fiddle (thnx @Thomas)测试