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

标签 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个教程,第二周完成了五个教程,第三周完成了7个教程,第四周完成了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  |      

在这里,在第一周,乔完成了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中生成

最佳答案

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

对于查询一个,您只需要在类型'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

关于sql-server-2005 - 将内容放入SQL Server 2005中的日期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5008560/

相关文章:

python - Pandas 数据透视多索引表,无聚合

SQL Server 2005 (Express) - 登录与用户

sql-server - 转置并用标志识别单元格

r - r中如何将长表转换为宽表?

php - MySQL 将数据透视为年月

sql - Oracle PIVOT,两次?

sql-server - SQL Server - 更改 PK 数据类型的最佳方法是什么?

匹配此模式的正则表达式 [LHB][0-9]{12}

sql-server - 比较 sql 中的 uniqueidentifier 和字符串哪个更快?

.net - FluentNHibernate 为 bool 设置默认列值