STUFF函数产生多行

时间:2015-09-02 11:08:19

标签: sql sql-server sql-server-2008

虽然这是一个非常简单的查询,但我仍然不知道在下面的查询中我哪里出错了

SELECT 
STUFF((SELECT ', ' + Package.Name  FROM Package WHERE Subscribed.PackID = Package.ID 
FOR XML PATH('')), 1, 1,'') [PackName]
FROM Subscribed  
WHERE 
Subscribed.UsrID = 1234 AND 
Subscribed.DateOfEnd <= CAST(GETDATE() AS DATE) AND
(Subscribed.Status = 0 OR Subscribed.Status = 1) 

因为我期待如下所示的结果:

PackName
---------------------------------
Demo Notification, EditedPackage

但这是我得到的结果如下所示

PackName
---------------------------------
Demo Notification
EditedPackage

所以任何评论我哪里错了。

3 个答案:

答案 0 :(得分:0)

如果只想要一行,则将所有逻辑移动到子查询中:

SELECT STUFF((SELECT ', ' + p.Name 
              FROM Package p JOIN
                   Subscribed s
                   ON s.PackID = p.ID 
              WHERE s.UsrID = 1234 AND 
                    s.DateOfEnd <= CAST(GETDATE() AS DATE) AND
                    s.Status IN (0, 1)
              FOR XML PATH('')), 1, 1, ''
            ) as [PackName];

否则,您将为Subscribed表中的每一行获得一个单独的行。

答案 1 :(得分:0)

尝试以下内容:

SELECT 
STUFF((SELECT ', ' + CAST(Package.Name AS VARCHAR(10)) [text()]  
       FROM Package 
       WHERE Subscribed.PackID = Package.ID 
       FOR XML PATH(''), TYPE)
       .value('.','NVARCHAR(MAX)'),1,1,' ') [PackName]
FROM Subscribed  
WHERE 
Subscribed.UsrID = 1234 AND 
Subscribed.DateOfEnd <= CAST(GETDATE() AS DATE) AND
(Subscribed.Status = 0 OR Subscribed.Status = 1) 

答案 2 :(得分:0)

我的猜测是你需要GROUP或使用DISTINCT,如下所示

SELECT DISTINCT
      Subscribed.UsrID
    , ca.PackName
FROM Subscribed
      CROSS APPLY (
            SELECT
                  STUFF((
                        SELECT
                              ', ' + Package.Name
                        FROM Package
                        WHERE Subscribed.PackID = Package.ID
                        FOR xml PATH (''), TYPE
                  )
                  .value('.', 'NVARCHAR(MAX)'), 1, 1, ' ') [PackName]
      ) ca
WHERE Subscribed.UsrID = 1234
      AND Subscribed.DateOfEnd <= CAST(GETDATE() AS date)
      AND (Subscribed.Status = 0
      OR Subscribed.Status = 1)

我还使用了CROSS APPLY,以便子查询构成FROM子句的一部分