我在下面的查询中给出了学生缺席的天数。 DATEDIFF和DATEPART计算工作日和假期不应计入缺席日。缺少的日子存储在studentTable的两个字段中,分别来自日期和日期。所以缺席的日子是在日期范围内。如果学生缺席一天,则会记录在2015年11月23日,2015年11月23日。如果学生缺席两天,那么2015年11月23日,2015年11月24日。
DECLARE @startDate DATE SET @startDate = '20151121'
DECLARE @endDate DATE SET @endDate = '20151123'
SELECT
a.studentName
,SUM(DATEDIFF(dd, fromDate, toDate)
- (DATEDIFF(wk, fromDate, toDate) * 2)
-CASE WHEN DATEPART(dw, fromDate) = 1 THEN 1 ELSE 0 END
+CASE WHEN DATEPART(dw, toDate) = 1 THEN 1 ELSE 0 END + 1 )- COUNT(h.holiday)
AS totalAbsentDay
FROM studentTable a
LEFT OUTER JOIN holiday h
ON h.holiday < a.toDate and h.holiday > a.fromDate
WHERE a.fromDate = @startDate AND a.toDate = @endDate
GROUP BY a.studentName
这里的问题是,当我尝试申报开始日期和结束日期时,它并没有给我正确的缺席日期。 例如,如果学生在2015年11月23日和2015年11月26日之间缺席(缺席4天,并且我宣布2015年11月22日开始日期和2015年11月27日结束日期),则查询不会给我3.的结果。
答案 0 :(得分:1)
下面的查询适用于给定的数据库方案,可能不是最佳解决方案,因为使用三级查询
DECLARE @startDate DATE SET @startDate = '2016-02-05'
DECLARE @endDate DATE SET @endDate = '2016-02-20'
SELECT
studentName,
SUM(AbsentDay) totalAbsentDay
FROM
(
SELECT
a.studentName
,DATEDIFF(dd, fromDate, toDate)
- (DATEDIFF(wk, fromDate, toDate) * 2)
-CASE WHEN DATEPART(dw, fromDate) = 1 THEN 1 ELSE 0 END
+CASE WHEN DATEPART(dw, toDate) = 1 THEN 1 ELSE 0 END + 1 - COUNT(h.holiday)
AS AbsentDay
FROM (
SELECT
studentName,-- Name,
CASE WHEN fromDate<@startDate THEN @startDate ELSE fromDate END fromDate,
CASE WHEN toDate>@endDate THEN @endDate ELSE toDate END toDate
FROM
StudentTable S
WHERE
S.toDate >= @startDate AND s.fromDate <= @endDate
) a
LEFT OUTER JOIN holiday h
ON h.holiday < a.toDate and h.holiday > a.fromDate
GROUP BY studentName, fromDate, toDate
) B
GROUP BY studentName
为了便于查询和更快执行,请考虑将studentTable
重新设计为类似idStudent
,AbsentDate
的内容..只是一个建议..