2015-12-02 36 views
1

如果我有其中的日期和时间是相同的或不同的数据如下:SQL将多行从一个表到一行多列

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相同但日期和时间不同,是否可以显示多行?

下面是原来的问题已经有了答案..

我已经看了thrrough所有有关这个问题的答案,但无法找到工作和大量的问题涉及到两个表中的任何代码。

我有一个表中有多行数据和多列包含不同的数据类型,例如

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

你有3对columms的一个最大? – Hogan

+0

嗨。它有所不同,最多可以有6. – Mally

+0

如果你想要id和datetime匹配,那么只需将其包含在连接中即可。连接是让事物保持在同一行的原因。 – Hogan

回答

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。

+0

谢谢。我会尝试。 – Mally

+0

经常人们实际上需要逗号分隔列表。 FOR XML有一个小窍门,那就是不需要知道会有多少个列表项。 – Hogan

+0

谢谢你的帮助 - 它的工作原理就是我想要它。 – Mally

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 

在您的要求中规定的“时间”一直被视为好,结果应该是像下面

enter image description here