匹配来自两个具有多个相同记录的表的记录

时间:2014-03-17 20:10:31

标签: sql sql-server

我有两个表需要根据条件验证/匹配完全匹配的记录。在某些情况下,同一个表中可能有两个相同的记录与第二个表中的两个记录匹配。我遇到的问题是从第一个表中获取不同的recordID,以使其与第二个表中的相应记录相匹配。

这是我的问题:

SELECT DISTINCT s.ID, 
AMT.ID, 
AMT.VerifiedSalesRecordID AS MatchID, 
AMT.ProductID
FROM AccountManagerTracker AS AMT JOIN Sales AS s
ON CHECKSUM (AMT.CompanyID, 
AMT.DateFulfilled, 
AMT.ProductID, 
AMT.GrossSalesAmount, 
AMT.NetSalesAmount, 
DATEPART(MM,AMT.CommissionMonth)) = CHECKSUM(s.CompanyID, 
s.DateFulfilled, 
s.ProductID, 
s.GrossSalesAmount, 
s.NetSalesAmount, 
DATEPART(MM,s.CommissionMonth))
WHERE s.ProductID IN (1,2,3,38)
AND AMT.VerifiedSalesRecordID IS NULL

结果:

T1ID  T2ID MatchID ProductID
14777   1   NULL    1
14813   2   NULL    1
14825   4   NULL    1
14933   6   NULL    3
14948   13  NULL    1
14948   14  NULL    1
15029   19  NULL    2
15043   17  NULL    2
15058   18  NULL    2
15151   22  NULL    1
15154   20  NULL    1
15156   25  NULL    2
15328   33  NULL    2
15330   30  NULL    1
15330   31  NULL    1

我只想要来自T1的不同记录。有什么想法吗?

修改 15330 30 NULL 1 15330 31 NULL 1 这两行是问题所在。它尝试使用表2中的两个不同记录来验证表1的相同记录。

2 个答案:

答案 0 :(得分:0)

这样的事情:

UPDATE AccountManagerTracker SET VerifiedSalesRecordID = (
SELECT s.ID 
FROM AccountManagerTracker JOIN Sales AS s
ON CHECKSUM (AccountManagerTracker .CompanyID, 
AccountManagerTracker .DateFulfilled, 
AccountManagerTracker .ProductID, 
AccountManagerTracker .GrossSalesAmount, 
AccountManagerTracker .NetSalesAmount, 
DATEPART(MM,AMT.CommissionMonth)) = CHECKSUM(s.CompanyID, 
s.DateFulfilled, 
s.ProductID, 
s.GrossSalesAmount, 
s.NetSalesAmount, 
DATEPART(MM,s.CommissionMonth))
WHERE s.ProductID IN (1,2,3,38)
AND AccountManagerTracker.VerifiedSalesRecordID IS NULL
)

你的FROM和你的JOIN正在为你提供正确的数据。您可以通过结果集看到数据是您想要的。由于您具有正确的s.ID,因此可以更新VerifiedSalesRecordID列。

如果您正在使用SQL Server,请确保在UPDATE调用之前使用BEGIN TRANSACTION ....这将使数据保持在未提交状态,以便您可以验证UPDATE的结果wothout提交结果到数据库

答案 1 :(得分:0)

我实际上找到了解决问题的更好方法。我需要表a的记录1与表b的记录1匹配,记录2与记录2等。这是我最终能够提出的解决方案。

UPDATE Table1 SET VerifiedSalesRecordID = t2.ID FROM (SELECT AMT.AMID, AMT.CompanyID, AMT.DateFulfilled, AMT.ProductID, AMT.GrossSalesAmount, AMT.NetSalesAmount, AMT.CommissionMonth, AMT.ID, AMT.VerifiedSalesRecordID, ROW_NUMBER() OVER (PARTITION BY AMT.AMID, AMT.CompanyID, AMT.ProductID, AMT.DateFulfilled ORDER BY AMT.CompanyID) AS RecordNum FROM Table1 AS AMT INNER JOIN ( SELECT AMID, CompanyID, DateFulfilled, ProductID, GrossSalesAmount, NetSalesAmount, COUNT(*) AS DupCount FROM Table1 GROUP BY AMID, CompanyID, DateFulfilled, ProductID, GrossSalesAmount, NetSalesAmount ) AS Dup ON AMT.AMID = Dup.AMID AND AMT.CompanyID = Dup.CompanyID AND AMT.DateFulfilled = Dup.DateFulfilled AND AMT.ProductID = Dup.ProductID AND AMT.GrossSalesAmount = Dup.GrossSalesAmount) AS t1 JOIN (SELECT s.SalesRepID, s.CompanyID, s.DateFulfilled, s.ProductID, s.GrossSalesAmount, s.NetSalesAmount, s.CommissionMonth, s.ID, s.Verified, ROW_NUMBER() OVER (PARTITION BY s.SalesRepID, s.CompanyID, s.ProductID, s.DateFulfilled ORDER BY s.CompanyID) AS RecordNum FROM Table2 AS s INNER JOIN ( SELECT SalesRepID, CompanyID, DateFulfilled, ProductID, GrossSalesAmount, NetSalesAmount, COUNT(*) AS DupCount FROM Table2 WHERE SalesTypeID = 2 GROUP BY SalesRepID, CompanyID, DateFulfilled, ProductID, GrossSalesAmount, NetSalesAmount ) AS Dup ON s.SalesRepID = Dup.SalesRepID AND s.CompanyID = Dup.CompanyID AND s.DateFulfilled = Dup.DateFulfilled AND s.ProductID = Dup.ProductID AND s.GrossSalesAmount = Dup.GrossSalesAmount) AS t2 ON t1.AMID = t2.SalesRepID AND t1.CompanyID = t2.CompanyID AND t1.DateFulfilled = t2.DateFulfilled AND t1.ProductID = (CASE WHEN t2.ProductID = 38 THEN t1.ProductID ELSE t2.ProductID END) AND t1.NetSalesAmount = t2.NetSalesAmount AND (CASE WHEN t1.ProductID = 3 THEN t2.GrossSalesAmount ELSE t1.GrossSalesAmount END) = t2.GrossSalesAmount AND DATEPART(MM,t1.CommissionMonth) = DATEPART(MM, t2.CommissionMonth) AND t1.RecordNum = t2.RecordNum WHERE Table1.ID = t1.ID AND t1.VerifiedSalesRecordID IS NULL AND t2.Verified = 0