SQL Server中多个用逗号分隔值的分组方式

时间:2018-08-02 05:58:16

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

我具有下面列出的下表结构

SELECT DISTINCT 'Grapes' AS fruit, 
    0.00 AS price
FROM yourTable
WHERE 'Grapes' NOT IN (fruits)

这是必需的输出

Budhol    COCODE    BEN      OBJ    SPARE2  SPARE1  TASKNO  Value   Field   Code
---------------------------------------------------------------------------------
362103    36        362101  991003  NULL    MA1001  NULL    4516    613030  001
362104    36        362104  991003  NULL    MA1001  NULL    9088    613030  002
362103    36        362101  991003  NULL    MA1001  NULL    3387    613030  003
362103    36        362101  991003  NULL    MA1001  NULL    4026    613030  004

即通过按组进行分组,我需要所有值的总和和逗号分隔的代码

我在下面的查询中尝试过,但是输出不匹配,无法获取所有列的所有代码

Budhol  COCODE  BEN      OBJ    SPARE2  SPARE1  TASKNO  Value   Field   Code
---------------------------------------------------------------------------------
362103  36      362101  991003  NULL    MA1001  NULL    11929   613030  001,003,001
362104  36      362104  991003  NULL    MA1001  NULL    9088    613030  002

3 个答案:

答案 0 :(得分:5)

问题似乎与某些列中的NULL值有关。特别是,SPARE1SPARE2列可以采用NULL的值,并且您的意图是使这些NULL的值相等。在下面的查询中,我用COALESCE将它们包装在连接的两边,现在我得到了预期的输出。

SELECT B.BEN, B.Budhol, B.COCODE, B.FIELD, B.OBJ, B.SPARE1, B.SPARE2,    
    SUM(B.value) AS Value,
    Code = STUFF((SELECT ', ' + Code FROM temp2 t
                  WHERE t.BEN = B.BEN AND t.Budhol = B.Budhol AND t.COCODE = B.COCODE AND
                        t.FIELD = B.FIELD AND
                        COALESCE(t.SPARE1, '') = COALESCE(B.SPARE1, '') AND
                        COALESCE(t.SPARE2, '') = COALESCE(B.SPARE2, '')
                 FOR XML PATH('')), 1,1, '')
FROM temp2 B
GROUP BY B.BEN, B.Budhol, B.COCODE, B.FIELD, B.OBJ, B.SPARE1, B.SPARE2;

enter image description here

Demo

答案 1 :(得分:2)

内部查询和外部查询使用相同的别名(B)。您必须使用其他别名(B1和B2)来区分它们:

SELECT B1.BEN, B1.Budhol, B1.COCODE, B1.FIELD, B1.OBJ, B1.SPARE1, B1.SPARE2,    
       SUM(B1.value) as Value ,
       STUFF((SELECT ', ' + Code 
              FROM #temp2 b2 
              WHERE b2.BEN = B1.BEN and b2.Budhol = B1.Budhol and b2.COCODE = B1.COCODE and b2.FIELD = B1.FIELD and 
                    isnull(b2.SPARE1,'') = isnull(B1.SPARE1,'') and isnull(b2.SPARE2,'') = isnull(B1.SPARE2,'')
              FOR XML PATH('')), 1,1, '') as Code
FROM #temp2 B1
GROUP BY B1.BEN,B.Budhol, B1.COCODE, B1.FIELD, B1.OBJ, B1.SPARE1, B1.SPARE2;

更新: 另外,正如Tim Biegeleisen所看到的,当两个值均为null(null是一个空状态,不是一个值)时, b2.spare2 = b1.spare2 将返回false,因此您应该将这些null状态转换为可以使用合并或isull函数进行比较的值: isnull(b2.spare2,'')= isull(b1.spare2,'')

答案 2 :(得分:0)

CREATE TABLE #Table1
    ([Budhol] int, [COCODE] int, [BEN] int, [OBJ] int, [SPARE2] varchar(4), [SPARE1] varchar(6), [TASKNO] varchar(4), [Value] int, [Field] int, [Code] varchar(100))
;

INSERT INTO #Table1
    ([Budhol], [COCODE], [BEN], [OBJ], [SPARE2], [SPARE1], [TASKNO], [Value], [Field], [Code])
VALUES
    (362103, 36, 362101, 991003, NULL, 'MA1001', NULL, 4516, 613030, 001),
    (362104, 36, 362104, 991003, NULL, 'MA1001', NULL, 9088, 613030, 002),
    (362103, 36, 362101, 991003, NULL, 'MA1001', NULL, 3387, 613030, 003),
    (362103, 36, 362101, 991003, NULL, 'MA1001', NULL, 4026, 613030, 004)

SELECT DISTINCT BUDHOL
    ,COCODE
    ,BEN
    ,OBJ
    ,SPARE2
    ,SPARE1
    ,TASKNO
    ,SUM(VALUE)VALUE
    ,FIELD
    ,STUFF((
            SELECT ','+'00' + CONVERT( VARCHAR(10),U.CODE)
            FROM #TABLE1 U
            WHERE B.BEN = U.BEN
                AND B.BUDHOL = U.BUDHOL
                AND B.COCODE = U.COCODE
                AND B.FIELD = U.FIELD
                AND B.SPARE1 = U.SPARE1


            FOR XML PATH('')
            ), 1, 1, '') AS USERLIST
FROM #TABLE1 B
GROUP BY [BUDHOL]
    ,[COCODE]
    ,[BEN]
    ,[OBJ]
    ,[SPARE2]
    ,[SPARE1]
    ,[TASKNO]
    ,[FIELD]

输出

BUDHOL  COCODE  BEN OBJ SPARE2  SPARE1  TASKNO  VALUE   FIELD   USERLIST
362103  36  362101  991003  NULL    MA1001  NULL    11929   613030  001,003,004
362104  36  362104  991003  NULL    MA1001  NULL    9088    613030  002