【问题标题】:Multiple groupby with comma separated values in SQL ServerSQL Server中具有逗号分隔值的多个groupby
【发布时间】:2018-08-02 05:58:16
【问题描述】:

我有下面列出的表结构

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

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

我尝试过以下查询,但输出与我获取所有列的所有代码不匹配

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 b 
                  WHERE b.BEN = B.BEN 
                    AND b.Budhol = B.Budhol 
                    AND b.COCODE = B.COCODE 
                    AND b.FIELD = B.FIELD  
                    AND b.SPARE1 = B.SPARE1 
                    AND b.SPARE2 = 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;

【问题讨论】:

  • @cars10mi 尝试过同样的方法,您可以查看我尝试过的查询
  • 362103的值怎么可以是17630?
  • @maulikkansara 立即查看
  • @Nilesh 请检查我发布的答案,您接受的答案无效,请检查

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


【解决方案1】:

问题似乎与您的某些列中的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;

Demo

【讨论】:

    【解决方案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 时,b2.spare2 = b1.spare2 将返回 false(null 是空状态,而不是值),因此您应该将这些 null 状态转换为一些可以使用 coalesce 或 isnull 函数比较的值:isnull(b2.spare2,'') = isnull(b1.spare2,'')

    【讨论】:

    • @Chanukya 你确定吗,我不明白它为什么会出错。 OP已接受答案。
    • @Nilesh,是的,我看到了明显的错误(别名),但我没有尝试您的数据,也没有看到您有空值。很高兴能帮上忙。
    • @Nilesh 检查我的答案
    【解决方案3】:
    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      相关资源
      最近更新 更多