SQL 将日期查询到具有唯一 ID 的新列中
SQL query date into new columns with unique ID
我有以下列、一个 5 位数的 ID、日期和一个值。仅当出现新日期时,ID 才会重复。
ID Date Value
11111 2014-12-31 45
22222 2014-12-31 435
33333 2014-12-31 11
11111 2014-12-30 5
22222 2014-12-30 2245
33333 2014-12-30 86
11111 2014-12-29 43
22222 2014-12-29 4678
33333 2014-12-29 2494
我正在尝试创建一个将显示以下内容的 SQL 查询(日期是列名):
ID 2014-12-31 2014-12-30 2014-12-29
11111 45 5 43
22222 435 2245 4678
33333 11 86 2494
使用 MS 执行此操作的最佳方法是什么 SQL。
谢谢
正如评论所指出的,您需要 PIVOT 数据。这是使用动态交叉表的一种方法。
阅读 Jeff Moden 的这篇文章以供参考:http://www.sqlservercentral.com/articles/Crosstab/65048
CREATE TABLE temp(
ID INT,
[Date] DATE,
Value INT
)
INSERT INTO temp VALUES
(11111, '2014-12-31', 45),
(22222, '2014-12-31', 435),
(33333, '2014-12-31', 11),
(11111, '2014-12-30', 5),
(22222, '2014-12-30', 2245),
(33333, '2014-12-30', 86),
(11111, '2014-12-29', 43),
(22222, '2014-12-29', 4678),
(33333, '2014-12-29', 2494);
DECLARE @sql1 VARCHAR(2000) = ''
DECLARE @sql2 VARCHAR(2000) = ''
DECLARE @sql3 VARCHAR(2000) = ''
SELECT @sql1 =
'SELECT
ID
'
SELECT @sql2 = @sql2 +
' ,MIN(CASE WHEN [Date] = CAST(''' + CONVERT(VARCHAR(10), [Date], 120) + ''' AS Date) THEN Value END) AS ['
+ CONVERT(VARCHAR(10), [Date], 120) + ']'+ CHAR(10)
FROM(
SELECT DISTINCT [Date] FROM temp
)t
ORDER BY [Date] DESC
SELECT @sql3 =
'FROM temp
GROUP BY ID
ORDER BY ID'
PRINT (@sql1 + @sql2 + @sql3)
EXEC (@sql1 + @sql2 + @sql3)
DROP TABLE temp
编辑:
如果您想使用固定名称,您需要为每个 Date
分配一个数字。这可以使用 ROW_NUMBER()
:
来完成
SELECT @sql2 = @sql2 +
' ,MIN(CASE WHEN [Date] = CAST(''' + CONVERT(VARCHAR(10), [Date], 120) + ''' AS Date) THEN Value END) AS [Date' + CONVERT(VARCHAR, rn) + ']'+ CHAR(10)
FROM(
SELECT
[Date],
rn = ROW_NUMBER() OVER(ORDER BY [Date])
FROM (
SELECT DISTINCT [Date]FROM temp
)x
)t
ORDER BY [Date] DESC
我有以下列、一个 5 位数的 ID、日期和一个值。仅当出现新日期时,ID 才会重复。
ID Date Value
11111 2014-12-31 45
22222 2014-12-31 435
33333 2014-12-31 11
11111 2014-12-30 5
22222 2014-12-30 2245
33333 2014-12-30 86
11111 2014-12-29 43
22222 2014-12-29 4678
33333 2014-12-29 2494
我正在尝试创建一个将显示以下内容的 SQL 查询(日期是列名):
ID 2014-12-31 2014-12-30 2014-12-29
11111 45 5 43
22222 435 2245 4678
33333 11 86 2494
使用 MS 执行此操作的最佳方法是什么 SQL。
谢谢
正如评论所指出的,您需要 PIVOT 数据。这是使用动态交叉表的一种方法。
阅读 Jeff Moden 的这篇文章以供参考:http://www.sqlservercentral.com/articles/Crosstab/65048
CREATE TABLE temp(
ID INT,
[Date] DATE,
Value INT
)
INSERT INTO temp VALUES
(11111, '2014-12-31', 45),
(22222, '2014-12-31', 435),
(33333, '2014-12-31', 11),
(11111, '2014-12-30', 5),
(22222, '2014-12-30', 2245),
(33333, '2014-12-30', 86),
(11111, '2014-12-29', 43),
(22222, '2014-12-29', 4678),
(33333, '2014-12-29', 2494);
DECLARE @sql1 VARCHAR(2000) = ''
DECLARE @sql2 VARCHAR(2000) = ''
DECLARE @sql3 VARCHAR(2000) = ''
SELECT @sql1 =
'SELECT
ID
'
SELECT @sql2 = @sql2 +
' ,MIN(CASE WHEN [Date] = CAST(''' + CONVERT(VARCHAR(10), [Date], 120) + ''' AS Date) THEN Value END) AS ['
+ CONVERT(VARCHAR(10), [Date], 120) + ']'+ CHAR(10)
FROM(
SELECT DISTINCT [Date] FROM temp
)t
ORDER BY [Date] DESC
SELECT @sql3 =
'FROM temp
GROUP BY ID
ORDER BY ID'
PRINT (@sql1 + @sql2 + @sql3)
EXEC (@sql1 + @sql2 + @sql3)
DROP TABLE temp
编辑:
如果您想使用固定名称,您需要为每个 Date
分配一个数字。这可以使用 ROW_NUMBER()
:
SELECT @sql2 = @sql2 +
' ,MIN(CASE WHEN [Date] = CAST(''' + CONVERT(VARCHAR(10), [Date], 120) + ''' AS Date) THEN Value END) AS [Date' + CONVERT(VARCHAR, rn) + ']'+ CHAR(10)
FROM(
SELECT
[Date],
rn = ROW_NUMBER() OVER(ORDER BY [Date])
FROM (
SELECT DISTINCT [Date]FROM temp
)x
)t
ORDER BY [Date] DESC