在2个表中将父项与子行值的精确匹配联系起来

时间:2012-12-20 08:36:14

标签: sql-server sql-server-2008 sql-server-2008-r2 sql-server-2012

我有2个表格,结构如下:

表1(Tb1):

MasId Int, ItemId int, Quantity int
1          1           10
1          2           5
1          3           18
2          2           3
2          4           8

表2(Tb2):

MasId Int, ItemId int, Quantity int
10          1           10
10          2           5
10          3           18
6           2           3
6           4           8

我希望将Tb1与Tb2与ItemIdQuantity列匹配。并获得以下查询:

Tb1.MasId   Tb2.MasId
1           10
2           6

Table1和Table2包含大约2000000条记录。我使用SQL Server 2012

编辑1

在Tb1和Tb2中存在以下记录:

Tb1中:

MasId, ItemId, Quantity
3      15       10
3      16       2

Tb2的:

MasId, ItemId, Quantity
20     15      10
20     18      5

Tb1.MasId和Tb2.MasId不匹配。

3 个答案:

答案 0 :(得分:1)

以下查询available as a SqlFiddle即使使用棘手的数据也会返回正确的结果:

SELECT
   Tb1MasId = A1.MasId,
   Tb2MasId = B1.MasId
FROM
   (
      SELECT
         MasID,
         Pattern = Checksum_Agg(Binary_Checksum(ItemId, Quantity))
      FROM dbo.Tb1
      GROUP BY MasId
   ) A1
   INNER JOIN (
      SELECT
         MasID,
         Pattern = Checksum_Agg(Binary_Checksum(ItemId, Quantity))
      FROM dbo.Tb2
      GROUP BY MasId
   ) B1
      ON A1.Pattern = B1.Pattern
      AND NOT EXISTS (
         SELECT * 
         FROM
            (
               SELECT A2.ItemID, A2.Quantity
               FROM dbo.Tb1 A2
               WHERE A1.MasID = A2.MasID
               UNION ALL
               SELECT B2.ItemID, B2.Quantity
               FROM dbo.Tb2 B2
               WHERE B1.MasId = B2.MasID
            ) X
         GROUP BY ItemID, Quantity
         HAVING Count(*) = 1
      );

页面上的其他答案对my SqlFiddle中的示例数据给出的结果不正确。具体来说,将以下数据添加到Tb2将会中断X.L.Ant's current query(由于未检测到2, 8不属于,因此会显示错误匹配8, 3, 18

INSERT dbo.Tb2
VALUES
   (7, 1, 10),
   (7, 2, 5),
   (7, 3, 17),
   (8, 3, 18),
   (8, 2, 3),
   (8, 4, 8);

答案 1 :(得分:0)

尝试:

SELECT Tb1.MasId AS MasId1, Tb2.MasId AS MasId2
FROM Tb1, Tb2, (SELECT MasId, COUNT(MasId) AS Cnt FROM Tb1 GROUP BY MasId) Cnt
WHERE Tb1.ItemId = Tb2.ItemId
  AND Tb1.Quantity = Tb2.Quantity
  AND Tb1.MasId = Cnt.MasId
GROUP BY Tb1.MasId, Tb2.MasId, Cnt.Cnt
HAVING COUNT(Tb1.MasId) = Cnt.Cnt

请参阅SQLFiddle

答案 2 :(得分:0)

您也可以按照以下方式进行分组

SELECT Tb1.MasId, Tb2.MasId
       FROM Tb1 
          INNER JOIN Tb2 
             ON Tb1.ItemId = Tb2.ItemId
             AND Tb1.Quantity = Tb2.Quantity
 group by Tb1.MasId, Tb2.MasId