2017-04-24 41 views
0

我有如下表:SQL服務器合併到行單列

SID AttributeID ValueID 
120  1  3 
120  2  4 
120  1  2 
120  2  2 

我wan't到行具有相同屬性Id結合起來,有這樣的事情:

SID AttributeID ValueID 
120  1  3, 2 
120  2  4, 2 

我曾嘗試STUFF功能,但我得到這個錯誤:

Conversion failed when converting the varchar value ',' to data type int.

查詢(更新後):

SELECT AttributeID, 
abc = STUFF((SELECT ',' + CAST(ValueID as varchar(250)) FROM SubjectDetails 
WHERE SubjectID=120 FOR XML PATH ('')), 1, 1, '') 
FROM SubjectDetails WHERE SubjectID=120 GROUP BY AttributeID 

結果:

AttributeID abc 
1   3,2,4,2 
2   3,2,4,2 
+3

鑄造/轉換'ValueID'成基於文本的類型(即'CHAR','VARCHAR'等...) – Kidiskidvogingogin

+0

我認爲它必須可能與int太 – berthos

回答

3

當您正在使用的代碼:

SELECT AttributeID, 
abc = STUFF((SELECT ',' + ValueID FROM SubjectDetails FOR XML PATH ('')), 1, 1, '') 
FROM SubjectDetails WHERE SubjectID=120 GROUP BY AttributeID 

你正在建設一個字符串,所以你不能沒有鑄造它在那裏使用INT,例如

...+ CAST(ValueID AS NVARCHAR(10))... 

我注意到,你的代碼不會給你你需要什麼,你需要:

SELECT AttributeID, 
STUFF((SELECT ',' + CAST(ValueID as varchar(250)) FROM SubjectDetails AS S 
WHERE [SID]=120 
AND S.AttributeID = SD.AttributeID FOR XML PATH ('')), 1, 1, '') AS abc 
FROM SubjectDetails AS SD 
WHERE [SID]=120 
GROUP BY AttributeID 

我已經改變了它是如何只別名,因爲你用我相信該方法將在被廢棄未來版本的MS SQL Server,如果您使用的MS SQL服務器是...

+0

仍然不是100%好,我更新了我的問題 – berthos

+0

重新創建表後,我無法複製MS SQL 2016上的錯誤。你使用的是什麼數據庫引擎和版本?此外,發現您的代碼存在問題,更新我的答案以包含您將需要的代碼以獲得期望的結果。 – Leonidas199x

+0

正是這個問題,我只是想發佈我的答案!我忘了做兩個選擇之間的鏈接 – berthos

3

根據the documents,SQL Server存在數據類型優先級。 你特別看這(去除的多餘數據

  1. int
  2. ...

...

  1. ...
  2. varchar (including varchar(max))

因此,我們知道,一個int比VARCHAR高,所以SQL服務器會嘗試和轉換','爲int類型。 它不能讓它出錯!

一個解決辦法是顯式轉換整型列ValueID爲varchar第一,那麼你應該沒有問題:

SELECT AttributeID, 
abc = STUFF((SELECT ',' + CAST(ValueID as varchar(250)) FROM SubjectDetails FOR XML PATH ('')), 1, 1, '') 
FROM SubjectDetails WHERE SubjectID=120 GROUP BY AttributeID 

注:我不知道你的ValueID列有多長等等我只是隨機選擇varchar(250)


更新 你得到個理由同樣的結果是因爲對於您的SubjectDetails表中的每一行,您都得到該行的ValueID s,其中SubjectID 120。 這是因爲這一行(用**突出顯示);

以下更正:

SELECT AttributeID, 
abc = STUFF((SELECT ',' + CAST(ValueID as varchar(250)) FROM SubjectDetails 
WHERE **SubjectID=120** FOR XML PATH ('')), 1, 1, '') 
FROM SubjectDetails WHERE SubjectID=120 GROUP BY AttributeID 

如果你的行匹配在一起,就像下面,就應該得到ValueID S中的行匹配ValueID S與你應該得到你想要的結果:

更正確的:

SELECT outerSD.AttributeID, 
abc = STUFF(( SELECT ',' + CAST(innerSD.ValueID as varchar(250)) 
       FROM SubjectDetails AS innerSD 
       WHERE innerSD.SubjectID = outerSD.SubjectID 
       FOR XML PATH ('')), 1, 1, '') 
FROM SubjectDetails AS outerSD 
WHERE outerSD.SubjectID=120 
GROUP BY outerSD.AttributeID 
+0

仍然不是100%好,我更新了我的問題 – berthos

+0

更新的答案也是正確的 – berthos

0
;With Cte([SID], AttributeID ,ValueID) 
AS 
(
SELECT 120,1, 3 UNION ALL 
SELECT 120,2, 4 UNION ALL 
SELECT 120,1, 2 UNION ALL 
SELECT 120,2, 2 
) 
SELECT DISTINCT [SID],AttributeID, REVERSE(STUFF((SELECT DISTINCT ', '+ CAST(ValueID AS VARCHAR(10)) 
FROM CTE I 
WHERE I.AttributeID =o.AttributeID FOR XML PATH('')),1,2,''))AS ValueID 
FROM Cte o 

輸出

SID|AttributeID|ValueID 
120 |1 | 3 ,2 
120 |2 | 4 ,2