如何在不弄乱数据的情况下将多行连接到单行?

How to concatenate multiple rows to single row without messing up the data?

我是 sql 服务器的新手,在使用 FOR XML 代码时发现了一个问题。 我的报表生成器正在使用 sql 服务器 2014。

我有 table 比如:

Field Accessory
1.I AA
1.I BB
1.I CC
1.II AA
1.III AA
1.III BB
1.IV AA
1.IV BB
1.V AA

并且结果要求是:

Field Accessory
1.I AA,BB,CC
1.II AA
1.III AA,BB
1.IV AA,BB
1.V AA

但是,我得到了这个:

Field Accessory
1.I AA,BB,CC,AA,AA,BB,AA,BB,AA
1.II AA,BB,CC,AA,AA,BB,AA,BB,AA
1.III AA,BB,CC,AA,AA,BB,AA,BB,AA
1.IV AA,BB,CC,AA,AA,BB,AA,BB,AA
1.V AA,BB,CC,AA,AA,BB,AA,BB,AA

这种table分组使用FOR XML路径合适吗? 谢谢!

查询是:

SELECT
       Radi.Field,
       (SELECT
               Acce.AccessoryId+','
        FROM
               FieldAcce
               INNER JOIN Radi ON FieldAcce.RadiSer = Radi.RadiSer
               INNER JOIN Acce ON FieldAcce.AcceSer = Acce.AcceSer
        WHERE
               Radi.Id LIKE UPPER (@RNO)
               AND Radi.CourseID LIKE @CourseID
               AND Radi.PhaseId LIKE @PhaseID
        ORDER BY
               Radi.Field
        FOR XML PATH('')) AS [Accessory]
FROM
        FieldAcce
        INNER JOIN Radi ON FieldAcce.RadiSer = Radi.RadiSer
        INNER JOIN Acce ON FieldAcce.AcceSer = Acce.AcceSer
WHERE
        Radi.Id LIKE UPPER (@RNO)
        AND Radi.CourseID LIKE @CourseID
        AND Radi.PhaseId LIKE @PhaseID
GROUP BY
        Radi.Field
        Acce.AccessoryId
ORDER BY
        Radi.Field

新的查询如下(未添加STUFF()部分时有效):

SELECT
    r.Field,
    STUFF(  
        (SELECT
            ', ' + Acce.AccessoryId
         FROM
            Radi
            INNER JOIN FieldAcce ON Radi.RadiSer = FieldAcce.RadiSer
            LEFT OUTER JOIN Acce ON FieldAcce.AcceSer = Acce.AcceSer
         WHERE
            Radi.Id LIKE UPPER (@RNO)
            AND Radi.CourseId LIKE @CourseID
            AND LEFT (Radi.PlanSetupId,1) LIKE @PhaseID
            AND r.Field = Radi.Field
         ORDER BY
            Radi.Field
         FOR XML PATH(''))
          ), 1, 1, '') AS [Accessory]
FROM
    Radi r
    INNER JOIN FieldAcce ON r.RadiSer = FieldAcce.RadiSer
    LEFT OUTER JOIN Acce ON FieldAcce.AcceSer = Acce.AcceSer
WHERE
    Radi.Id LIKE UPPER (@RNO)
    AND Radi.CourseId LIKE @CourseID
    AND LEFT (Radi.PlanSetupId,1) LIKE @PhaseID
    AND EXISTS
        (SELECT
            r.Field
         FROM
            Radi cry
         WHERE
            r.Field = cry.Field
            AND cry.Field NOT LIKE N'APER%')
GROUP BY
    r.Field
ORDER BY
    r.Field

附件的示例数据是

Accessory
EDW45IN
A10
A06
EDW60IN
EDW45OUT
NDS
A084

sub-query 应该引用主查询 FieldAccessoryId

SELECT
       Radi.Field,
       (SELECT
               a.AccessoryId+','
        FROM
               FieldAcce fa
               INNER JOIN Radi r ON fa.RadiSer = r.RadiSer
               INNER JOIN Acce a ON fa.AcceSer = a.AcceSer
        WHERE
               r.Id LIKE UPPER (@RNO)
               AND r.CourseID LIKE @CourseID
               AND r.PhaseId LIKE @PhaseID
               -- add the following 2 lines
               AND r.Field = Radi.Field
               AND a.AccessoryId = Acce.AccessoryId
        ORDER BY
               r.Field
        FOR XML PATH('')) AS [Accessory]
FROM
        FieldAcce
        INNER JOIN Radi ON FieldAcce.RadiSer = Radi.RadiSer
        INNER JOIN Acce ON FieldAcce.AcceSer = Acce.AcceSer
WHERE
        Radi.Id LIKE UPPER (@RNO)
        AND Radi.CourseID LIKE @CourseID
        AND Radi.PhaseId LIKE @PhaseID
GROUP BY
        Radi.Field,
        Acce.AccessoryId
ORDER BY
        Radi.Field