我有一个包含date
,employeeID
(int)和ShiftWorked
的表格(可以是夜晚/白天/周末或晚上)。每个员工和日期组合都有一行
我想构建一个查询,让我了解在名册期间的每个日期之前和之后的一周中有多少人工作过夜班。
--------------------------------------------------------------------------
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)
怎么样?
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
答案 1 :(得分: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');如果不是这种情况,则需要对日期比较进行更多调整。
答案 2 :(得分:0)
您可以通过将ROSTER表连接到自身来将其拉出,从而为每个员工和每天创建多个结果行。否则,您的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]