2012-04-24 14 views
1

date,employeeID(int)、ShiftWorked(夜間/日/週末または夕方)のテーブルがあります。各従業員と日付の組み合わせの行があります日付範囲で条件が満たされているMSSQLの選択カウント

ロスタ期間内の各日付の前後に夜間シフトを行った人数をカウントするクエリを作成したいと考えています。

-------------------------------------------------------------------------- 
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

あなたがすでに試したことを投稿してください。 –

答えて

1

次のクエリでは、2つの列を返します。

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

OR取得する)は夜勤が働いていなかった。

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

+0

あなたが探しているものは100%確かではありませんが、いくつかのオプションが追加されました – gordatron

0

あなたは名簿に参加することによってそれをやってのけることができますテーブルを作成して、従業員1日あたりの結果行をいくつか作成します。それ以外の場合、GROUP BY句は、結果の行を元のテーブルの日付に後続する期間からグループ化します。参照(名簿)日付と基準日後7日間に7日前まで取捨選択夜に取り組んできました(個別の)人々の数:

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

ありがとうございました!私は最後のjoin節とwhere節を入れ替えましたが、それはちょうど私が質問した方法のせいかもしれません – user1353276

関連する問題