SQL Server - 连接3个表并更新标志

时间:2017-05-16 21:50:28

标签: sql-server database tsql

目前我创建的存储过程基于数据来源(S1,S2,S3)创建了3个表。在这样做时,它使用排名功能根据产品编号和日期对每条记录进行排名。

SELECT 
    a.*, b.ProductNumber, 
    CAST(CASE 
            WHEN b.ProductNumber = b.NewProductNumber) 
               THEN 1 
               ELSE 0 
         END AS BIT) 'NewProduct', 
    ROW_NUMBER() OVER (PARTITION BY ProductNumber ORDER BY Date) 'RowNum'
INTO 
    Table1
FROM 
    Table2 a 
LEFT OUTER JOIN  
    Table3 b ON a.ID = b.ID and b.Source = 'S1'

SELECT 
    a.*, b.ProductNumber, 
    CAST(CASE 
            WHEN b.ProductNumber = b.NewProductNumber)  
               THEN 1 
               ELSE 0 
         END AS BIT) 'NewProduct', 
    ROW_NUMBER() OVER (PARTITION BY ProductNumber ORDER BY Date) 'RowNum'
INTO 
    Table1
FROM 
    Table2 a 
LEFT OUTER JOIN 
    Table3 b ON a.ID = b.ID and b.Source = 'S2'

SELECT 
    a.*, b.ProductNumber, 
    CAST(CASE 
            WHEN b.ProductNumber = b.NewProductNumber) 
               THEN 1 
               ELSE 0 
         END AS BIT) 'NewProduct', 
    ROW_NUMBER() OVER (PARTITION BY ProductNumber ORDER BY Date) 'RowNum'
INTO 
    Table1
FROM 
    Table2 a 
LEFT OUTER JOIN 
    Table3 b ON a.ID = b.ID and b.Source = 'S3'

然后将此数据汇集到一个Collective表中,并根据'RowNum'更新'NewProduct'标志

SELECT 
    ProductNumber, NewProductNumber, 
    CAST('Source1' AS VARCHAR(15)) 'SourceName',  
    NewProduct, RowNum
INTO 
    CollectiveTable
FROM 
    Table1

UNION ALL

SELECT 
    ProductNumber, NewProductNumber, 
    CAST('Source2' AS VARCHAR(15)),      
    NewProduct, RowNum
FROM
    Table2

UNION ALL

SELECT 
    ProductNumber, NewProductNumber, 
    CAST('Source3' AS VARCHAR(15)),      
    NewProduct, RowNum
FROM 
    Table3;

UPDATE CollectiveTable
SET NewProduct = 0
WHERE NewProduct = 1
  AND RowNum != 1;

我的问题是,在CollectiveTable中,如果我最终得到来自同一产品并标记为“新产品”的多个来源的记录,我希望原始来源是唯一标记为“新产品”的来源新的“,我该怎么做。

我真的不想使用光标。

例如,

CollectiveTable

ProductNumber   NewProductNumber    SourceName      NewProduct      RowNum
--------------------------------------------------------------------------
99999           99999               Source1         1               1
99999           99999               Source2         1               1
99999           99999               Source3         1               1
00000           00000               Source2         1               1
00000           00000               Source1         1               1
12345           12345               Source3         1               1
12345           12345               Source2         1               1

对于产品99999,“原始来源”将是Source1,00000 Source1,& 12345 Source2

因此,我想更新以下记录的“NewProduct”标志:

ProductNumber   NewProductNumber    SourceName      NewProduct      RowNum
--------------------------------------------------------------------------
99999           99999               Source1         1               1
99999           99999               Source2         0               1
99999           99999               Source3         0               1
00000           00000               Source2         0               1
00000           00000               Source1         1               1
12345           12345               Source3         0               1
12345           12345               Source2         1               1

有什么好办法可以解决这个问题。非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

首先,为了帮助我们理解问题并尝试使用解决方案,我是否可以建议为表定义和样本记录添加代码,不一定是100%准确或复杂,只需足以与之关联。

其次,我的答案基于几个假设,其中一些是:

  • 您不会介意在完成正常工作量之后纠正标志的效率低下。
  • 您只有3个来源。

最后,如果没有其他方法完全击败,这肯定有很大的改进潜力:

-- Correct flags of any record that should be corrected due to presence of Source1.
UPDATE C2C3
SET NewProduct = 0
FROM CollectiveTable AS C2C3
INNER JOIN CollectiveTable AS C1 ON C2C3.ProductNumber = C1.ProductNumber AND C1.SourceName = 'SOURCE1'
WHERE C2C3.SourceName IN ('Source2', 'Source3')

-- Correct flags of Source3 records who weren't corrected by previous step.
UPDATE C3
SET NewProduct = 0
FROM CollectiveTable AS C3
INNER JOIN CollectiveTable AS C1C2 ON C1C2.ProductNumber = C3.ProductNumber AND C1C2.SourceName IN ('SOURCE1', 'SOURCE2')
WHERE C3.SourceName IN ('Source3')