SQL Server将行组合为单个列

时间:2017-04-24 13:08:34

标签: sql-server database rows

我有下表:

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

我不想将具有相同AttributeID的行组合起来,得到类似的东西:

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

我尝试过STUFF功能,但是我收到了这个错误:

  

转换varchar值时转换失败''数据类型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 个答案:

答案 0 :(得分:3)

使用代码时:

iex(1)> "a B.c |> D.e + f g h + i" |> Code.string_to_quoted! |> Macro.to_string
"a(B.c() |> D.e() + f(g(h + i)))"

您正在构建一个字符串,因此您不能在不使用它的情况下使用INT,例如

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

我注意到您的代码无法满足您的需求,您需要:

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

我已经改变了别名的方式,因为你使用的方法我认为在MS SQL Server的未来版本中将被弃用,如果你使用的是MS SQL服务器......

答案 1 :(得分:3)

根据the documents,SQL Server有一个数据类型优先级。 您特别关注这一点(删除多余的数据

  
      
  1. INT
  2.   
  3. ...
  4.         

    ...

         
        
    1. ...
    2.   
    3. varchar(包括varchar(max))
    4.   

因此我们知道int高于varchar,因此SQL Server将尝试将','转换为int。 它不会出错!

解决方法是首先将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表中的每一行,您获得的行ValueIDSubjectID 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的行的ValueID,您应该得到您想要的结果:

更正确:

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

答案 2 :(得分: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