访问SQL - 两个日期之间每月计算天数

时间:2018-02-14 15:48:56

标签: sql ms-access

我有两张桌子 - [Students]其中包含学生名单(以及他们老师的名字),以及[Absence Extract]其中包含任何学生的每个缺席记录(以及开始和结束日期和总天数。

我正在尝试编写一个查询,将教师缺席的日子分组,然后显示他们每个月有多少天缺席。我已经开始撰写以下查询,其中我已经显示了我在1月和2月丢失了几天的计算(我会在其他月份添加计算),但是这个例子没有工作,好像他们在1月和2月有15天的缺席,这是两个月的15天。

有人可以指出我正确的方向吗?

SELECT 
     [Students].[Teacher Name] AS [Teacher], 
     SUM(IIF(ae.[Absence End Date] >= #1/1/18# AND ae.[Absence Start Date] <= #1/31/18#,[Total Days],0)) AS [Jan Days],
     SUM(IIF(ae.[Absence End Date] >= #2/1/18# AND ae.[Absence Start Date] <= #2/28/18#,[Total Days],0)) AS [Feb Days]

FROM 
     [Students] 
INNER JOIN 
     [Absence Extract] ae ON [Students].[ID] = [ae].[Student ID]
GROUP BY [Students].[Teacher Name];

1 个答案:

答案 0 :(得分:0)

请勿使用计算列总天数,因为它会将月份甚至年份的开始日期和结束日期之间的差异相加。考虑计算单独的持续时间:

  1. 开始日期开始日期月结束的缺席持续时间
  2. 结束日期月的第一个结束日期的缺席时间
  3. 然后将聚合连接在一起。例如,缺席范围2018年1月30日 - 2018年2月2日:

    1. 第一个查询计算从1月30日到1月31日(月末)的天数,分组为1月份
    2. 第二个查询从2月1日(月初)到2月2日计算,分组到2月份
    3. 加入查询与教师,年份和月份对齐,并使用算术加法+计算总持续时间,其中1天的2天结果和不同行的2月的2天结果
    4. 开始日期查询

      SELECT 
           s.[Teacher Name] AS [Teacher], 
           Year(ae.[Absence End Date]) As Year_Absence,
           MonthName(Month(ae.[Absence Start Date]), TRUE) As Month_Absence,
           SUM(DateDiff('d', ae.[Absence Start Date], 
                             DateAdd('m', 1, ae.[Absence Start Date]) - 
                                             Day(ae.[Absence Start Date]))) As StartDuration
      FROM 
           [Students] s 
      INNER JOIN 
           [Absence Extract] ae ON s[ID] = ae.[Student ID]
      GROUP BY s.[Teacher Name],
               Year(ae.[Absence Start Date])
               MonthName(Month(ae.[Absence Start Date]), TRUE);
      

      结束日期查询

      SELECT 
           s.[Teacher Name] AS [Teacher], 
           Year(ae.[Absence End Date]) As Year_Absence,
           MonthName(Month(ae.[Absence End Date]), TRUE) As Month_Absence,
           SUM(DateDiff('d', ae.[Absence End Date], 
                             ae.[Absence End Date] - 
                                        (Day(ae.[Absence End Date])-1))) As EndDateDuration
      FROM 
           [Students] s 
      INNER JOIN 
           [Absence Extract] ae ON s[ID] = ae.[Student ID]
      GROUP BY s.[Teacher Name],
               Year(ae.[Absence End Date])
               MonthName(Month(ae.[Absence End Date]), TRUE);
      

      加入查询 (长格式)

      SELECT s.[Teacher Name], 
             s.Year_Absence,
             s.Month_Absence,
             NZ(s.StartDuration) + NZ(e.EndDateDuration) As TotalDuration
      FROM startdate_query s
      LEFT JOIN enddate_query e 
          ON s.[Teacher Name] = e.[Teacher Name]
          AND s.Year_Absence = e.Year_Absence
          AND s.Month_Absence = e.Month_Absence
      

      由于您正在寻找一个包含月份列的广泛报告来维护缺省持续时间的总和,请考虑MS Access自己的crosstab query

      交叉表查询 (宽格式)

      TRANSFORM SUM(NZ(s.StartDuration) + NZ(e.EndDateDuration)) AS [SumDays]
      SELECT s.[Teacher Name], 
             s.Year_Absence
      FROM startdate_query s
      LEFT JOIN enddate_query e 
          ON s.[Teacher Name] = e.[Teacher Name]
          AND s.Year_Absence = e.Year_Absence
          AND s.Month_Absence = e.Month_Absence
      
      GROUP BY s.[Teacher Name], 
               s.Year_Absence
      PIVOT s.Month_Absence IN ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
                                'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
      

      当然,如果没有实际数据,所有这些都是未经测试的。因此,可能需要进行各种调整。