选择日期范围内的特定日期

Posted

技术标签:

【中文标题】选择日期范围内的特定日期【英文标题】:Selecting certain days in a date range 【发布时间】:2016-02-15 23:28:41 【问题描述】:

我有下面的查询,它给出了学生缺勤的天数。 DATEDIFF 和 DATEPART 计算工作日和节假日不应算作缺勤日。缺勤天数存储在 studentTable 中 fromDate 和 toDate 两个字段中。所以缺席的日子在一个日期范围内。如果学生缺勤一天,则记录为 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的结果。

【问题讨论】:

您确定WHERE a.fromDate = @startDate AND a.toDate = @endDate 是正确的过滤器..?我的意思是如果过滤器注释掉了,结果是正确的? 是的,苏西洛。如果您注释掉 DECLARE 部分和 WHERE 子句。查询工作正常。 我根据自己的看法尝试了自己的数据。即使在declarewhere 注释掉如果学生缺席中有多个假期,您的查询也会失败。可能是我的看法是错误的..所以请您分享表格结构和示例数据..? 我已经仔细检查过,在注释掉声明和位置后它可以工作。 还需要表结构和样本数据.. 【参考方案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 重新设计为idStudentAbsentDate..只是一个建议..

【讨论】:

以上是关于选择日期范围内的特定日期的主要内容,如果未能解决你的问题,请参考以下文章

选择日期范围,根据关闭条件计算范围内的多条记录,按班次分组

jquery ui 多日期选择器数据范围没有周末

mysql选择范围内的日期时间对象

选择日期范围内的分组值总和(窗口函数)

MySQL:选择两个日期范围内的所有数据

SQL在where语句中使用日期范围的选择子查询来确定该日期范围内的最大值