【问题标题】:SQL Comma Separated List from Multiple Columns来自多列的 SQL 逗号分隔列表
【发布时间】:2009-10-23 01:38:09
【问题描述】:

我的数据如下所示:

CUSTOMER_ID  OPERDAYSJUL  OPERDAYSAUG  OPERDAYSSEP ... OPERDAYSJUN
1            30           15           2
2            5            1            0
3            6            0            12
4            12           5            23

对于每个 customer_id,我想要一个以逗号分隔的列表,指示客户操作的月份:

CUSTOMER_ID  OPERATING_MONTHS
1            Jul, Aug, Sep
2            Jul, Aug
3            Jul, Sep
4            Jul, Aug, Sep

等等。如何使用 SQL Server 2005 SQL(不是 T-SQL)轻松生成这个逗号分隔的列表?

我在 Stack Overflow 和其他地方看到的大多数解决方案似乎都是基于连接多行值而不是列值来创建逗号分隔的列表:

  • T-SQL
  • 用于 XML 路径('')
  • 与 REPLACE/STUFF/SUBSTRING 结合的相关子查询

我是否遗漏了一些明显的东西?在此先感谢您提供帮助或指向适当的现有解决方案。

【问题讨论】:

  • 为什么说“不是 T-SQL”? T-SQL 只是 SQL Server 使用的 SQL 方言的名称。 en.wikipedia.org/wiki/Microsoft_SQL_Server#T-SQL
  • 感谢卢克的洞察力;我似乎用错了这个词。我想将答案限制为简单的 SELECT 查询语法,不受局部变量、临时表、循环等的影响。再次感谢。

标签: sql sql-server sql-server-2005


【解决方案1】:

这会去掉多余的逗号

SELECT 
  CUSTOMER_ID,
  SUBSTRING(
    CASE WHEN OPERDAYSJUL > 0 THEN ', Jul' ELSE '' END +
    CASE WHEN OPERDAYSAUG > 0 THEN ', Aug' ELSE '' END +
    ...
    CASE WHEN OPERDAYSJUN > 0 THEN ', Jun' ELSE '' END,
   3, 255)
FROM TheTable

【讨论】:

    【解决方案2】:
    declare @t table (CUSTOMER_ID int
      , OPERDAYSJUL int
      , OPERDAYSAUG int
      , OPERDAYSSEP int
      -- ... rest of 9 months here
      );
    
    insert into @t (CUSTOMER_ID, OPERDAYSJUL, OPERDAYSAUG, OPERDAYSSEP)
    select 1, 30, 15, 22 union all
    select 2, 0, 10, 10 union all
    select 3, 0, 0, 10 union all
    select 4, 0, 0, 0 union all
    select 5, 10, 0, 10 union all
    select 6, 10, 10, 0 union all
    select 7, 0, 10, 0 union all
    select 8, 10, 0, 0;    
    
    with cte_months as (
    select CUSTOMER_ID
      , case when OPERDAYSJUL=0 then '' else ', Jul' end 
      + case when OPERDAYSAUG=0 then '' else ', Aug' end
      + case when OPERDAYSSEP=0 then '' else ', Sep' end
      -- ... rest of 9 months here
      as month_list
     from @t)
     select CUSTOMER_ID, substring(month_list, 3, 70) 
     from cte_months;
    

    【讨论】:

      【解决方案3】:

      你可以这样做。

      CONCAT(CASE OPERDAYSJUL > 0 THEN "Jul," ELSE "" END,CASE OPERDAYSAUG > 0 THEN "Aug" ELSE "" END ... )
      

      【讨论】:

      • 谢谢蒂姆;我现在正在尝试这个。我认为您可能需要用另一种方法包装对 concat() 的调用以去除尾随逗号。
      • 谢谢蒂姆,这成功了。我使用了 DJ 的答案,因为它看起来更简洁和正确,但由于他似乎是您想法的延伸,因此我在应有的地方给予您信任。再次感谢。
      【解决方案4】:

      假设您的表有 13 列(一年中的每个月 1 列 + CUSTOMER_ID),您可以编写如下内容:

      SELECT 
        CUSTOMER_ID,
        CASE OPERDAYSJUL > 0 THEN 'Jul,' ELSE '' END +
        CASE OPERDAYSAUG > 0 THEN 'Aug,' ELSE '' END +
        ...
      FROM MyTable
      

      并使用 CASE 语句构建一个代表逗号分隔列表的字符串,每个月一个。

      【讨论】:

      • 我也想过,但是你怎么去掉结尾的逗号?
      • 谢谢 pmarflee;你如何从最后一个值中去掉逗号?
      【解决方案5】:
      select 
         customer_id,
         case when len(operating_month) > 0 then 
             left(operating_month, len(operating_month) - 1)
         else 
             operating_month 
         end as operating_month
      from
      (
         SELECT CUSTOMER_ID,  
         CASE OPERDAYSJUL > 0 THEN 'Jul,' ELSE '' END 
         +  CASE OPERDAYSAUG > 0 THEN 'Aug,' ELSE '' END 
         +  ... 
         as operating_month
         FROM MyTable
      ) as x
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-19
        • 2018-08-07
        • 1970-01-01
        • 2016-10-24
        • 1970-01-01
        • 2014-05-31
        相关资源
        最近更新 更多