使用另一个表中的最新值更新多个列

时间:2015-09-22 08:20:40

标签: sql-server sql-update

这是数据:

[TABLE_1]

id | prod1  | date1  | prod2  | date2  | prod3  | date3 |
---|--------|--------|--------|--------|--------|-------|
1  | null   | null   | null   | null   | null   | null  |
2  | null   | null   | null   | null   | null   | null  |
3  | null   | null   | null   | null   | null   | null  |

[TABLE_2]

id   |  date       |   product |  
-----|-------------|-----------|
1    |  20140101   |   X       | 
1    |  20140102   |   Y       | 
1    |  20140103   |   Z       | 

2    |  20141201   |   data    | 
2    |  20141201   |   Y       | 
2    |  20141201   |   Z       | 

3    |  20150101   |   data2   | 
3    |  20150101   |   data3   | 
3    |  20160101   |   X       | 

这两个表都有其他未在此列出的列。 格式为date:yyyymmdd,数据类型为int[ TABLE_2 ]没有空行,只是试图让上面的样本更具可读性。

以下是目标:

我需要更新[ TABLE_1 ] prod1date1prod2date2prod3date3product收集[ TABLE_2 ],其值为date

必须对数据进行排序,以便"最新的" product变为prod1, 第二个最新product将为prod2,第三个为prod3

最新product =最大date(int)。 如果日期相同,订单并不重要。 (见id = 2和id = 3)。

更新[ TABLE_1 ]应为:

id | prod1  | date1    | prod2  | date2    | prod3  | date3    |
---|--------|----------|--------|----------|--------|----------|
1  | Z      | 20140103 | Y      | 20140102 | X      | 20140101 |  
2  | data   | 20141201 | Y      | 20141201 | Z      | 20141201 |  
3  | X      | 20160101 | data2  | 20150101 | data3  | 20150101 |

最终目标是获得以下内容:

[TABLE_3]

id | order1             | order2               | order3     |  + Columns from [ TABLE_1 ]
---|--------------------|----------------------|------------|--------------------------
1  | 20140103:Z         | 20140102:Y           | 20140103:Z |
2  | 20141201:data:Y:Z  | NULL                 | NULL       |
3  | 20160101:X         | 20150101:data2:data3 | NULL       |

我必须承认这超出了我的知识,我还没有尝试过任何事情。

我应该使用JOIN或SELECT子查询吗?

我是否应该尝试在一个SQL-clause中或者在3个步骤中创建它, 当时每个prod& date对?

创建[ TABLE_3 ]怎么样? 它必须包含[ TABLE_1 ]的列。 最简单的方法是从[ TABLE_2 ] -data还是更新[ TABLE_1 ]创建它?

任何帮助都将受到高度赞赏。 提前致谢。

我会在评论中发布一些自己的镜头。

2 个答案:

答案 0 :(得分:1)

在查看之后(在我的评论之后),存储过程最好,您可以调用以将数据视为数据透视表,并取消TABLE_1。显然,如果你需要使这个动态,你需要研究动态支点,这对CTE来说有点黑客攻击:

CREATE PROCEDURE DBO.VIEW_AS_PIVOTED_DATA

AS

;WITH CTE AS (
SELECT ID, [DATE], 'DATE' + CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY [DATE] DESC) AS VARCHAR) AS [RN]
FROM TABLE_2)
, CTE2 AS (
SELECT ID, PRODUCT, 'PROD' + CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY [DATE] DESC) AS VARCHAR) AS [RN]
FROM TABLE_2)
, CTE3 AS (
SELECT ID, [DATE1], [DATE2], [DATE3]
FROM CTE
PIVOT(MAX([DATE]) FOR RN IN ([DATE1],[DATE2],[DATE3])) PIV)
, CTE4 AS (
SELECT ID, [PROD1], [PROD2], [PROD3]
FROM CTE2
PIVOT(MAX(PRODUCT) FOR RN IN ([PROD1],[PROD2],[PROD3])) PIV)
SELECT A.ID, [PROD1], [DATE1], [PROD2], [DATE2], [PROD3], [DATE3]
FROM CTE3 AS A
JOIN CTE4 AS B
ON A.ID=B.ID

答案 1 :(得分:0)

结构:

WITH ranked AS (
    SELECT [id]
          ,[date]
          ,[product]
          ,row_number() over (partition by id order by date desc) rn
      FROM [sistemy].[dbo].[TABLE_2]
)
SELECT id, [prod1],[date1],[prod2],[date2],[prod3],[date3]  
FROM 
(
    SELECT id, type+cast(rn as varchar(1)) col, value
    FROM ranked
    CROSS APPLY 
    (
        SELECT 'date', CAST([date] AS varchar(8))
        UNION ALL
        SELECT 'prod', product
    ) ca(type, value)
) unpivoted 
PIVOT
(
    max(value)
    for col IN ([prod1],[date1],[prod2],[date2],[prod3],[date3])
) pivoted

您需要采取一些措施来实现目标。

按日期对您的产品进行排名:

SELECT [id]
  ,[date]
  ,[product]
  ,row_number() over (partition by id order by date desc) rn
FROM [sistemy].[dbo].[TABLE_2]

将您的dateproduct列放到一列中。您可以使用UNPIVOT OR CROSS APPLY语句。我更喜欢CROSS APPLY

SELECT id, type+cast(rn as varchar(1)) col, value
FROM ranked
CROSS APPLY 
(
    SELECT 'date', CAST([date] AS varchar(8))
    UNION ALL
    SELECT 'prod', product
) ca(type, value)

或使用UNPIVOT

的相同结果
SELECT id, type+cast(rn as varchar(1)) col, value
FROM (
    SELECT [id], 
        rn, 
        CAST([date] AS varchar(500)) date, 
        CAST([product] AS varchar(500)) prod 
    FROM ranked) t
UNPIVOT 
(
    value FOR type IN (date, product)
) unpvt

最后您使用PIVOTE并获得结果。

相关问题