2012-04-24 78 views
1

我有一個包含date,employeeID(int)和ShiftWorked(可以是night/day/weekend或evening)的表。每個員工和日期組合都有一排在一個日期範圍內滿足條件的MSSQL select count

我想構建一個查詢,該查詢給出了有多少人在名單期間的每個日期之前和之後的一週中有過多次夜班工作。

-------------------------------------------------------------------------- 
Date (yyyy-MM-dd)  | CountOfNightshifts(for 1 week either side of date) 
-------------------------------------------------------------------------- 

2012-1-1    | 8 
2012-1-2    | 12 
2012-1-3    | 11 
2012-1-4    | 6 
etc     | etc 

我希望這是明確的。我花了好幾天的時間試圖讓這個工作,但我沒有得到任何地方。

例如:

SELECT COUNT(id), [date] 
FROM ROSTER 
WHERE Shift = night AND [date] BETWEEN DATEADD(D,-7,[date]) AND DATEADD(d,7,[date]) 
GROUP by [date] 
group by [date] 

這會給我日期列表幾夜的是,當日的計數 - 並非所有值夜班的前7天與日之後。

+0

請發表您已經嘗試過的內容。 – 2012-04-24 09:55:41

回答

1

下面的查詢將返回兩列:參考(名單)日期和已經在晚上基準日後七天前篩選工作七天(不同)的人數。

SELECT tmain.date, 
(
    SELECT COUNT(DISTINCT taux.employeeId) 
    FROM roster taux 
    WHERE taux.shiftWorked = 'night' 
     AND taux.date >= DATEADD(DAY, -7, tmain.date) 
     AND taux.date <= DATEADD(DAY, 7, tmain.date) 
) AS [number_of_distinct_people_with_night_shift] 
FROM roster tmain 
ORDER BY tmain.date; 

注1:通常我更喜歡加入了子查詢,但我想這個解決方案更易於閱讀。注2:我假設日期值的時間分量是不相關的,並且所有的日期都有相同的時間(即'00:00:00.00');如果不是這種情況,那麼在日期比較中需要做更多的調整。

1

這個怎麼樣?更

SELECT 
    [date] 
    ,count(*) 
FROM 
    Shifts as s 
WHERE 
    s.Date > DATEADD(day,-7,GETDATE()) 
    AND ShiftWorked = 'Night' 
GROUP BY 
    date 

http://sqlfiddle.com/#!3/e88cc/1

數據位:

http://sqlfiddle.com/#!3/b7793/2

如果你只在特定日期感興趣,那麼你可以使用:

DECLARE @target datetime 
SET @target = GETDATE() 

SELECT 
    count(*) as NightShifts 
FROM 
    Shifts as s 
WHERE 
    ShiftWorked = 'Night' 
    AND s.Date > DATEADD(day,-7,@target) 
AND s.Date < DATEADD(day,7,@target) 

http://sqlfiddle.com/#!3/b7793/20

但是如果你有另一個實際上有周期的表(例如,賬單或工資日期):

DECLARE @target datetime 
SET @target = GETDATE() 

SELECT 
p.periodDate 
    ,count(*) 
FROM 
    Shifts as s 
INNER JOIN periods as p 
    ON s.date > dateadd(day,-7,p.periodDate) 
     AND s.date < dateadd(day,7,p.periodDate) 
WHERE 
    ShiftWorked = 'Night' 
GROUP BY p.periodDate 

http://sqlfiddle.com/#!3/fc54d/2

或獲得)時,沒有夜班後處理:

SELECT 
    p.periodDate 
    ,ISNULL(t.num,0) as nightShifts 
FROM 
    periods as p  
    LEFT OUTER JOIN (
     SELECT 
      p.periodDate 
      ,count(*) as num 
     FROM 
      Shifts as s 
      INNER JOIN periods as P 
       ON s.date > dateadd(day,-7,p.periodDate) 
       AND s.date < dateadd(day,7,p.periodDate) 
     WHERE 
      ShiftWorked = 'Night' 
     GROUP BY p.periodDate 
    ) as t 
      ON p.periodDate = t.periodDate 

http://sqlfiddle.com/#!3/fc54d/11

+0

謝謝@ gordatron的回覆 - 但也許我的問題不清楚(第一次問)。我稍微修改了鏈接[鏈接](http://sqlfiddle.com/#!3/1ded6/2)。這給了我一個特定的日子 - 而不是在7天內有多少夜班日期。 – user1353276 2012-04-24 10:41:06

+0

不是100%確定你在找什麼,但在那裏增加了一些選項 – gordatron 2012-04-24 10:51:07

0

您可以通過加入名冊把它關閉表格自身,從而爲每位員工和每天創建多個結果行。否則,您的GROUP BY子句會將您所處的期間的結果行分組到原始表的日期中。

SELECT 
    r.[date], 
    COUNT(period.id) 
FROM ROSTER r 
JOIN ROSTER period 
    ON period.employeeID=r.employeeID 
    AND period.shift = night 
    AND r.[date] BETWEEN DATEADD(d,-7,period.[date]) and DATEADD(d,7,period.[date]) 
WHERE 
    r.shift = night 
GROUP BY r.[date] 
+0

謝謝你!我交換了最後的連接子句和where子句 - 但這可能只是因爲我問了這個問題 – user1353276 2012-04-24 12:16:16