【问题标题】:Get first record from duplicate records and use its identity in other tables从重复记录中获取第一条记录并在其他表中使用其标识
【发布时间】:2015-08-13 08:44:02
【问题描述】:

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

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

Company 是主表,product 是子表。产品包含公司的参考。现在这些是我的临时表,我需要将这些表中的正确值插入到我的主表中。

我想插入如下记录

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

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

有人可以帮忙吗?

【问题讨论】:

    标签: sql-server unique


    【解决方案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 中的行是否唯一。 IE。公司代码为 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,并通过 TempCompany(名称)从 Product 额外加入到 Company。额外的连接是为了正确处理具有 CompanyCode 00516 和 CompanyCode 00135 的 Product1:

    --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
    

    【讨论】:

    • 对不起,我忘了在我的问题中添加一些记录。我已经更新了我的问题。 DISTINCT 对我不起作用,因为虽然 TempCompany 表中的前 2 条记录是不同的,但我只想将第一条记录保存到 Company 表中并在 Product 表中使用其 IDENTITY。
    • 所以你基本上想使用 CompanyName 作为 distinct 的键?在您的示例数据中,实际上忽略了 CompanyCode 135。但仍将要插入的产品与 CompanyCode 135 匹配?我本来希望将两个公司代码都存储在公司表中。为什么不想存储两行?
    • 我更新了答案,在最后添加了一个编辑部分,应该满足您的要求。虽然不完全确定我喜欢这个解决方案,但我想这完全取决于您的规范/为什么您不想存储公司名称和公司代码的所有组合。
    猜你喜欢
    • 2018-11-20
    • 2011-01-11
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多