将内容放入SQL Server 2005中的日期范围

时间:2011-02-15 19:29:36

标签: sql-server-2005 pivot

我有一个包含周范围(周数,开始日期,结束日期)的表和一个包含教程日期的表(用于编写教师(教师ID,tutorial_date,教程类型(A或B))。

我想创建两个查询,显示顶部的周范围(第1周,第2周),旁边的教师名称与每个块中该周的日期范围内的教程计数(类型“A”)那个星期。

结果应如下所示:

“A”型教程的计数

Tutor|Week One|Week Two|Week Three|Week Four|Total
Joe  |   3    |   5    |    7     |    8    | 23        
Sam  |   2    |   4    |    3     |    8    | 17        

意味着Joe在第一周完成了3个教程,第二周完成了5个教程,第3周完成了7个教学,第4周完成了8个教学。

第二个查询应显示教程类型“A”和“B”

的总计
Tutor|Week One|Week Two|Week Three|Week Four|Total   |
Joe  |  3/1   |   5/3  |   7/2    |   8/2   | 23/8   |     
Sam  |  2/3   |   4/4  |   3/2    |   8/3   | 17/12  |      

在第一周,Joe完成了3个A类教程和1个B类教程。

教程的样本表数据(第一周)

Tutor | Tutorial_ID | Tutorial Date |Type|
------------------------------------------
Joe   |    1        | 2011-01-01    | A  |
Joe   |    2        | 2011-01-02    | A  |
Joe   |    3        | 2011-01-03    | A  |
Joe   |    4        | 2011-01-03    | B  |
Sam   |    5        | 2011-01-01    | A  |
Sam   |    6        | 2011-01-02    | A  |
Sam   |    7        | 2011-01-03    | B  |

周表如下:

weekNumber |startDate |endDate
1          |2011-01-01|2011-01-15

我想在SQL Server 2005中生成这个

1 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。

对于查询一个,您只需要{A}类型的PIVOT,那么您只需PIVOT

select *
from 
(
  select w1.tutor
    , w1.type
    , wk.weeknumber
  from w1
  inner join wk
    on w1.tutorialdate between wk.startdate and wk.enddate
  where w1.type = 'a'
) x
pivot
(
  count(type)
  for weeknumber in ([1])
)p 

通过演示

查看SQL Fiddle

或者您可以使用带有Count()声明的CASE

select w1.tutor
  , COUNT(CASE WHEN w1.type = 'A' THEN 1 ELSE null END) [Week One]
from w1
inner join wk
  on w1.tutorialdate between wk.startdate and wk.enddate
group by w1.tutor

请参阅SQL Fiddle with Demo

但对于第二个查询,我只会使用Count() CASE

select w1.tutor
  , Cast(COUNT(CASE WHEN w1.type = 'A' AND wk.weeknumber = 1 THEN 1 ELSE null END) as varchar(10))
     + ' / '
     + Cast(COUNT(CASE WHEN w1.type = 'B' AND wk.weeknumber = 1 THEN 1 ELSE null END) as varchar(10)) [Week One]
   , Cast(COUNT(CASE WHEN w1.type = 'A' AND wk.weeknumber = 2 THEN 1 ELSE null END) as varchar(10))
     + ' / '
     + Cast(COUNT(CASE WHEN w1.type = 'B' AND wk.weeknumber = 2 THEN 1 ELSE null END) as varchar(10)) [Week Two]
from w1
inner join wk
  on w1.tutorialdate between wk.startdate and wk.enddate
group by w1.tutor

请参阅SQL Fiddle with Demo

编辑为AndriyM指出第二个可以用PIVOT完成这里是第二个查询的解决方案:

SELECT *
FROM
(
  select distinct w1.tutor
    , wk.weeknumber
    , left(total, len(total)-1) Totals
  FROM w1
  inner join wk
      on w1.tutorialdate between wk.startdate and wk.enddate
  CROSS APPLY
  (
    SELECT cast(count(w2.type) as varchar(max)) + ' / '
    from w1 w2
    inner join wk wk2
      on w2.tutorialdate between wk2.startdate and wk2.enddate
    WHERE w2.tutor = w1.tutor
      AND wk2.weeknumber = wk.weeknumber
    group by w2.tutor, wk2.weeknumber, w2.type
    FOR XML PATH('')
  )  D ( total )
)  x
PIVOT
(
  min(totals)
  for weeknumber in ([1], [2])
) p

请参阅SQL Fiddle with Demo