2011-02-15 55 views
3

我有一個包含周範圍(週數,開始日期,結束日期)和一個包含教程日期的表格(用於編寫導師(導師ID,tutorial_date,教程類型(A或B)把東西放入SQL Server 2005中的日期範圍

我想創建兩個查詢,顯示頂部的周範圍(第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   

含義喬完成在一個星期3個教程,五兩個,7周在三個星期,並在8周4

第二查詢應顯示教程類型「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 |  

在這裏,在一個星期內,喬做類型A的3個教程和類型B的1

樣本表數據的教程(一週)

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中

+0

那麼,爲什麼WeekNumber 1有兩週的日期範圍...這是要對你的數據預計....或者你可以依靠?日期開始的那一週的哪一週? – Lamak 2011-02-15 20:01:53

+0

由於業務規則,我的星期日期範圍是硬編碼的。 – Caveatrob 2011-02-15 20:38:53

回答

1

有幾個方法可以做到這一點。

對於查詢一個,在這裏你只需要PIVOT在 'A' 型,那麼你可以做一個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