这是数据:
[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 ]
prod1
,date1
,prod2
,date2
,prod3
,date3
从product
收集[ 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 ]
创建它?
任何帮助都将受到高度赞赏。 提前致谢。
我会在评论中发布一些自己的镜头。
答案 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]
将您的date
和product
列放到一列中。您可以使用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
并获得结果。