2012-10-12 40 views
4

我有一個要求,根據項目ID連接我查詢的不同行中的值。SQL在主鍵上連接行值

例如,我有以下幾行數據。

GroupID LABEL VALUE UNIT 
    1 Name Henry 
    1 Guest Manny Guest 
    1 Room 12 
    1 Milk 10  Quart 
    1 Eggs 3  dozen 
    2 Name Mark Supervisor 
    2 Water 13  Litre 
    2 Milk 3  Gallons 
    2 Soap 12  bars 

而且作爲輸出,我希望得到以下

ItemID  VALUE 

1   Name: Henry; Guest:Manny Guest; Room:12; Milk:10 Quart; Eggs: 3 dozen; 

2   Name: Mark supervisor; Water: 13 litre; Milk: 3 Gallons; Soap: 12 bars; 

如何做到這一點嗎?

+0

[?和你有** **你試過到目前爲止,請] (http://www.whathaveyoutried.com) –

+0

CTE's。看起來很亂。 – Kobojunkie

回答

3

請嘗試:

SELECT DISTINCT a.GroupID AS ItemID,(
SELECT ISNULL(b.LABEL,'')+': '+ISNULL(b.VALUE,'')+' '+ISNULL(b.UNIT,'')+';' FROM TABLE b WHERE b.GroupID=a.GroupID 
FOR XML PATH('')) AS [VALUE] 
FROM TABLE a 
+1

爲了做我已經決定要做的事情+1。太。 : - ) - 使用XML是解決這個問題的最快和最簡單的方法。 – gotqn

+0

我也試過這個例子,實際上我有很多值可以在我的表中編譯。當我嘗試使用左連接將表連接到另一個表時,會發生這種情況。有沒有規則反對這個或是否可能在我的一端有一些錯誤? – Kobojunkie

+0

我認爲它在列標籤或值或單元NULL值becoz,請嘗試通過添加'ISNULL(b.Label,'')'而不是'b.Label'等 – TechDo

4

您可以編寫基於this exampleSQL Fiddle) - 它遞歸查詢現在包括代碼來處理在單位列NULL值。

WITH PRE 
    AS (SELECT *, 
       Row_number() 
        OVER ( 
        PARTITION BY GROUPID 
        ORDER BY GROUPID) RN 
     FROM TABLE1), 
    RECURSIVE 
    AS (SELECT *, 
       Cast(LABEL + ':' + VALUE + ' ' + Isnull(UNIT, '') + ';' AS 
        VARCHAR( 
        MAX)) 
        AS FINAL 
     FROM PRE 
     WHERE RN = 1 
     UNION ALL 
     SELECT t1.*, 
       FINAL 
       + Cast(t1.LABEL +':' + t1.VALUE +' '+ Isnull(t1.UNIT, '') + ';' 
       AS 
       VARCHAR(MAX)) 
     FROM PRE T1 
       INNER JOIN RECURSIVE T2 
         ON T1.GROUPID = T2.GROUPID 
          AND T1.RN = T2.RN + 1) 
SELECT T1.GROUPID, 
     T1.FINAL 
FROM RECURSIVE T1 
     INNER JOIN (SELECT Max(RN) RN, 
          GROUPID 
        FROM RECURSIVE 
        GROUP BY GROUPID) T2 
       ON T1.GROUPID = T2.GROUPID 
        AND t1.RN = T2.RN 
+0

我收到了一些奇怪的結果。我試過這個,而實際上我的表中至少有12行與連接的值沒有結果。 – Kobojunkie

+0

你看過SQL小提琴的例子嗎?它使用您在Q中發佈的數據,並根據您的要求提供結果。 您使用的數據差別很大嗎? – Gidil

+0

是的,我確實看過小提琴的例子。在我剛剛注意到的錯誤之後,似乎我不允許在遞歸方法內執行左連接。這似乎是我沒有得到任何東西的原因。 – Kobojunkie

3

檢查了這一點Concatenating Row Values in Transact-SQL有很多方法來解決這個問題。

Declare @t TABLE 
( 
    GroupID INT, 
    Label NVARCHAR(20), 
    Value NVARCHAR(20), 
    Unit NVARCHAR (50) 
) 

INSERT INTO @t 
VALUES (1,'Name','Henry','') 
     ,(1,'Guest','Manny','Guest') 
     ,(1,'Room','12','') 
     ,(1,'Milk','10','Quart') 
     ,(1,'Eggs','3','dozen') 
     ,(2,'Name','Mark','Supervisor') 
     ,(2,'Water','13','Litre') 
     ,(2,'Milk','3','Gallons') 
     ,(2,'Soap','12','bars') 

;With Cte As 
(
    Select 
      GroupId 
      ,Label = Label + ': ' + Value + ' ' + Unit 
    From @t 

) 

Select 
    GroupId 
    ,Value = Stuff((Select ';' + Cast(Label As Varchar(Max)) 
    From Cte c2 
    Where c1.GroupId = c2.GroupId 
    For Xml Path('')),1,1,'')+';' 

From Cte c1 
Group By c1.GroupId 

enter image description here

同時要注意堆棧溢出的Concatenate many rows into a single text string

2

全部工作〔實施例:

SET NOCOUNT ON 
GO 

DECLARE @SourceTable TABLE 
(
    GroupID INT, 
    LABEL NVARCHAR(20), 
    VALUE NVARCHAR(20), 
    UNIT NVARCHAR (50) 
) 

INSERT INTO @SourceTable (GroupID,LABEL,VALUE,UNIT) 
VALUES (1,'Name','Henry','') 
     ,(1,'Guest','Manny','Guest') 
     ,(1,'Room','12','') 
     ,(1,'Milk','10','Quart') 
     ,(1,'Eggs','3','dozen') 
     ,(2,'Name','Mark','Supervisor') 
     ,(2,'Water','13','Litre') 
     ,(2,'Milk','3','Gallons') 
     ,(2,'Soap','12','bars') 

SELECT DISTINCT GroupID 
     ,(SELECT SUBSTRING((SELECT ';' + LABEL +':'+VALUE+' '+UNIT FROM @SourceTable AS B WHERE A.GroupID=B.GroupID FOR XML PATH('')),2,200) AS CSV) 
FROM @SourceTable AS A 

SET NOCOUNT OFF 
GO