2015-12-02 103 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