合并查询中记录的列

时间:2014-04-30 14:14:43

标签: sql sql-server sql-server-2012

我面临着一个非常恼人的问题。

我有一个具有以下结构的表。

coursename - day1 - moment1 - day2 - moment2   - day3 - moment3  - day4 - moment4
course A   - mon  - morning - wed  - afternoon - NULL - NULL     - NULL - NULL
course B   - tue  - evening - thu  - evening   - NULL - NULL     - NULL - NULL
course C   - mon  - evening - tue  - evening   - wed  - morning  - thu  - evening
course D   - wed  - morning - thu  - morning   - sat  - afternoon- NULL - NULL

输出应该是

coursename - timetable
course A   - mon morning, wed afternoon
course B   - tue/thu evening
course C   - mon/tue/thu evening, wed morning
course D   - wed/thu morning, sat afternoon

我该如何查询类似的内容?我唯一能想到的就是使用嵌套的案例,但我担心会破坏性能。

我正在使用MS SQL Server 2012

1 个答案:

答案 0 :(得分:1)

如果我们有良好的字符串聚合功能,这可能会更漂亮,但只是为了给你一个想法:

with cte as (
-- unpivot days into strings
        select
            T.coursename, A.day, A.moment
        from Table1 as T
            outer apply (values
                  (T.day1, T.moment1),
                  (T.day2, T.moment2),
                  (T.day3, T.moment3),
                  (T.day4, T.moment4)
              ) as A(day, moment)  
), cte2 as (
-- concat all days for each moment
   select
       c.coursename, c.moment,
       stuff(
         (
           select '/' + t.day
           from cte as t
           where t.coursename = c.coursename and t.moment = c.moment
           for xml path(''), type
         ).value('.', 'nvarchar(max)')
       ,1,1,'') as days
   from cte as c
   group by c.coursename, c.moment
)
-- concat final timetable
select
    c.coursename,
    stuff(
      (
         select ', ' + t.days + ' ' + t.moment
         from cte2 as t
         where t.coursename = c.coursename
         for xml path(''), type
       ).value('.', 'nvarchar(max)')
     ,1,2,'') as timetable
from cte2 as c
group by c.coursename

<强> sql fiddle demo