从重复记录中获取第一条记录,并在其他表中使用其标识

时间:2015-08-13 08:44:02

标签: sql-server unique

我有两个临时表,其中有重复项。两个表包含如下记录。

DECLARE @TempCompany TABLE (TempCompanyCode VARCHAR(100), TempCompanyName VARCHAR(100))
INSERT INTO @TempCompany VALUES ('00516','Company1')
INSERT INTO @TempCompany VALUES ('00135','Company1')
INSERT INTO @TempCompany VALUES ('00324','Company2')
INSERT INTO @TempCompany VALUES ('00566','Company2')
SELECT * FROM @TempCompany 

DECLARE @TempProduct TABLE (TempProductCode VARCHAR(100), TempProductName VARCHAR(100), TempCompanyCode VARCHAR(100))
INSERT INTO @TempProduct VALUES ('001000279','Product1','00516')
INSERT INTO @TempProduct VALUES ('001000279','Product1','00135')
INSERT INTO @TempProduct VALUES ('001000300','Product2','00135')
INSERT INTO @TempProduct VALUES ('001000278','Product3','00566')
INSERT INTO @TempProduct VALUES ('001000278','Product3','00324')
INSERT INTO @TempProduct VALUES ('001000304','Product4','00566')
SELECT * FROM @TempProduct

公司是主表,产品是子表。产品包含公司参考。现在这些是我的临时表,我需要从这些表中插入适当的值到我的主表。

我想按以下方式插入记录

DECLARE @Company TABLE(CompanyID INT IDENTITY(1,1), CompanyCode VARCHAR(100), CompanyName VARCHAR(100))
INSERT INTO @Company VALUES ('00516','Company1')
DECLARE @IDOf00516 INT = @@IDENTITY
INSERT INTO @Company VALUES ('00324','Company2')
DECLARE @IDOf00324 INT = @@IDENTITY
SELECT * FROM @Company 

DECLARE @Product TABLE(ProductID INT IDENTITY(1,1), ProductCode VARCHAR(100), ProductName VARCHAR(100), CompanyID INT)
INSERT INTO @Product VALUES ('001000279','Product1',@IDOf00516)
INSERT INTO @Product VALUES ('001000300','Product2',@IDOf00516)
INSERT INTO @Product VALUES ('001000278','Product3',@IDOf00324)
INSERT INTO @Product VALUES ('001000300','Product4',@IDOf00324)
SELECT * FROM @Product

我附上了以下图片,了解运行查询时的外观。

How it should be inserted

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

我可能首先将tempCompany中的唯一记录插入到Company表中,然后从TempProduct执行插入操作,并查找插入的Company表。

即。第一次插入公司:

INSERT INTO @Company (CompanyCode, CompanyName)
SELECT temp.TempCompanyCode, temp.TempCompanyName 
FROM @TempCompany AS temp

然后使用联接插入产品以查找companyid:

INSERT INTO @Product (ProductCode, ProductName, CompanyId)
SELECT temp.TempProductCode, temp.TempProductName, c.CompanyID
FROM @TempProduct AS temp
    JOIN @Company AS c ON temp.TempCompanyCode = c.CompanyCode -- Lookup to find CompanyID

但是,这并未考虑重复项以及主表已插入记录的可能性。 添加重复并检查已存在的记录,最终结果可能如下所示:

--1. insert records not already in company table:
INSERT INTO @Company (CompanyCode, CompanyName)
SELECT DISTINCT temp.TempCompanyCode, temp.TempCompanyName 
FROM @TempCompany AS temp
    LEFT JOIN @Company AS c ON temp.TempCompanyCode = c.CompanyCode -- Will match Companies that already exists in @Companies
WHERE c.CompanyID IS NULL -- Company does not already exist
ORDER BY temp.TempCompanyCode 

--2. insert product records:
INSERT INTO @Product (ProductCode, ProductName, CompanyId)
SELECT DISTINCT temp.TempProductCode, temp.TempProductName, c.CompanyID
FROM @TempProduct AS temp
    JOIN @Company AS c ON temp.TempCompanyCode = c.CompanyCode -- Lookup to find CompanyID
    LEFT JOIN @Product AS p ON temp.TempProductCode = p.ProductCode AND temp.TempCompanyCode = c.CompanyCode -- Will match products that already exists in @Products
WHERE p.ProductID IS NULL -- Product does not already exists
ORDER BY c.CompanyID, temp.TempProductCode

--3. Check result
SELECT * FROM @Company
SELECT * FROM @Product

请注意,我使用LEFT JOIN并添加WHERE条件以检查主表中是否已存在记录。 使用MERGE语句可以很好地实现这一点 - 但我习惯于稍微不那么易读的LEFT JOIN / WHERE方法:)

修改

只有TempCompanyName用于确定TempCompany中的行是否唯一。即使用CopmpanyCode 00135的Company1应该插入。

为实现这一目标,我将利用ROW_NUMBER帮助查找要插入的公司行。我已经在@TempCompany中添加了一个标识列,以确保插入的第一行是使用的行(即确保00516用于Company1而不是00135)。

新的@TempCompany定义:

DECLARE @TempCompany TABLE (TempCompanyId INT IDENTITY(1,1), TempCompanyCode VARCHAR(100), TempCompanyName VARCHAR(100))

添加了row_number的更新脚本以及从Product到TempCompany(在名称上)到公司的额外连接。额外的连接是为了正确处理Product1与CompanyCode 00516和CompanyCode 00135:

--1. insert records not already in company table:
;WITH OrderedTempCompanyRows AS (SELECT ROW_NUMBER() OVER (PARTITION BY TempCompanyName ORDER BY TempCompanyId) AS RowNo, TempCompanyCode, TempCompanyName FROM @TempCompany)
INSERT INTO @Company (CompanyCode, CompanyName)
SELECT DISTINCT temp.TempCompanyCode, temp.TempCompanyName 
FROM OrderedTempCompanyRows temp
    LEFT JOIN @Company AS c ON temp.TempCompanyName = c.CompanyName -- Will match Companies that already exists in @Companies
WHERE temp.RowNo = 1 -- Only first company according to row_number
    AND c.CompanyID IS NULL -- Company does not already exist
ORDER BY temp.TempCompanyName 

--2. insert product records:
INSERT INTO @Product (ProductCode, ProductName, CompanyId)
SELECT DISTINCT temp.TempProductCode, temp.TempProductName, c.CompanyID
FROM @TempProduct AS temp
    JOIN @TempCompany tc ON temp.TempCompanyCode = tc.TempCompanyCode -- Find Companyname in @Tempcompany table
    JOIN @Company AS c ON tc.TempCompanyName = c.CompanyName -- Join to @Company on Companyname to find CompanyID
    LEFT JOIN @Product AS p ON temp.TempProductCode = p.ProductCode AND temp.TempCompanyCode = c.CompanyCode -- Will match products that already exists in @Products
WHERE p.ProductID IS NULL -- Product does not already exists
ORDER BY c.CompanyID, temp.TempProductName

--3. Check result
SELECT * FROM @Company
SELECT * FROM @Product