如果我的数据的日期和时间相同或不同如下:
ID Date LOC
1 2015-12-02 10:05 A
1 2015-12-02 10:05 B2
2 2015-12-02 10:05 D
2 2015-12-02 10:05 A7P
2 2015-12-02 10:06 AD
有没有办法显示以下内容:
ID DATE1 LOC1 DATE 2 LOC2 DATE 3 LOC3
1 2015-12-02 10:05 A 2015-12-02 10:05 B2
2 2015-12-02 10:05 D 2015-12-02 10:05 A7P
2 2015-12-02 10:06 AD
因此会有多行ID,但日期和时间不同?
我使用了下面的分区示例,这非常适合将数据放入我最初提出的一行中。但是当ID相同但日期和时间不同时,是否可以显示多行。
以下是已经得到回答的原始问题..
我看过所有与此问题相关的答案,但无法找到任何有效的代码,而且很多问题都与两个表有关。
我有一个包含多行数据的表和多个包含不同数据类型的列,例如
ID Date LOC
1 2015-11-05 10:05 A
1 2015-12-02 10:06 B2
2 2015-12-02 10:05 D
2 2015-12-02 10:05 A7P
2 2015-12-02 10:06 AD
对于每个ID,我只需要一行,所有数据都在多列中,例如
ID DATE1 LOC1 DATE 2 LOC2 DATE 3 LOC3
1 2015-11-05 10:05 A 2015-12-02 10:06 B2
2 2015-12-02 10:05 D 2015-12-02 10:05 A7P 2015-12-02 10:06 AD
这些可以包含重复的数据和一个或多个相同ID的行。
我尝试了一些pivot / unpivot sql代码但是我收到了关于unpivot中不同类型的错误。
非常感谢任何帮助。
答案 0 :(得分:0)
这是解决此问题的基本方法,首先制作row_number,然后再进行连接
WITH TAB_RN AS
(
SELECT ID, Date, LOC, ROW_NUMBER() OVER (PARTITION BY ID, Date ORDER BY LOC) AS RN
FROM YOUR_TABLE
)
SELECT T1.ID,
T1.Date AS DATE1, T1.LOC AS LOC1,
T2.Date AS DATE2, T2.LOC AS LOC2,
T3.Date AS DATE3, T3.LOC AS LOC3
FROM TAB_RN T1
LEFT JOIN TAB_RN T2 ON T1.ID = T2.ID AND T1.Date = T2.Date AND T2.RN = 2
LEFT JOIN TAB_RN T3 ON T1.ID = T3.ID AND T1.Date = T2.Date AND T3.RN = 3
WHERE T1.RN = 1
如果你不知道"有多少"然后你必须使用它作为模板来制作动态sql。
答案 1 :(得分:0)
我想我已经设法得到了这个,但我不确定这个是否有错误。
我为测试目的创建了一个示例表
CREATE TABLE Trace (
TraceID INT IDENTITY(1,1)
, ID INT
, [Date] DATETIME
, LOC NVARCHAR(50)
)
INSERT INTO Trace (ID, [Date], LOC)
VALUES
(1,'2015-12-02 10:05','A'),
(1,'2015-12-02 10:05','B2'),
(2,'2015-12-02 10:05','D'),
(2,'2015-12-02 10:05','A7P'),
(2,'2015-12-02 10:06','AD')
如果您希望根据每个ID的最大位置数(灵活列)获取记录,您可以尝试下面的脚本。
-- build up table to keep the values in 1 column and make a flag (StatusCode) out of it
SELECT
ROW_NUMBER() OVER (PARTITION BY ID, StatusCode ORDER BY TraceID, Pos) AS idx
, *
INTO #resultBuildUp
FROM (
SELECT
TraceID
, 2 AS [Pos]
, [ID]
, 'LOC' + CONVERT(NVARCHAR(50),(ROW_NUMBER() OVER (PARTITION BY ID, [Date] ORDER BY TraceID))) AS StatusCode
, LOC AS [val]
FROM Trace
UNION ALL
SELECT
TraceID
, 1 AS [Pos]
, [ID]
, 'DATE ' + CONVERT(NVARCHAR(50),(ROW_NUMBER() OVER (PARTITION BY ID, [Date] ORDER BY TraceID))) AS StatusCode
, REPLACE(CONVERT(NVARCHAR(50),[Date],111),'/','-') + ' ' + CONVERT(NVARCHAR(50),[Date],108) AS [val]
FROM Trace
) AS T
--this is a builder to create the "select" columns for PIVOT
SELECT
StatusCode
INTO #tmpDistinctColumns
FROM #resultBuildUp
GROUP BY
StatusCode
ORDER BY
min(TraceID)
, min(Pos)
DECLARE @distinct NVARCHAR(MAX) = ''
SET @distinct = (SELECT '[' + StatusCode + '],' AS [text()] FROM #tmpDistinctColumns FOR XML PATH(''))
SET @distinct = SUBSTRING(@distinct, 0, LEN(@distinct))
-- and lastly, the pivot query wherein I hid the position modifier(idx) for the query
EXEC ('
SELECT
ID
, ' + @distinct + '
FROM (
SELECT
idx,
ID,
StatusCode,
val
FROM #resultBuildUp
) AS s
PIVOT
(
MAX(Val)
FOR StatusCode IN (' + @distinct + ')
) AS pvt
')
-- drop all temporary tables built from above script
drop table #resultBuildUp
drop table #tmpDistinctColumns
您的要求中指定的“时间”也已被考虑,结果应如下所示