【问题标题】:Access SQL - Count days in each month between two datesAccess SQL - 计算两个日期之间每个月的天数
【发布时间】:2018-02-15 01:20:10
【问题描述】:

我有两个表 - [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];

【问题讨论】:

  • 您不想按月按老师显示吗?在这种情况下,您的分组不完整。
  • 嗨 krish,感谢您的回复。目前[Absence Extract] 中没有[month] 字段,因此我无法将其添加为分组依据。我打算为每个月编写一个计算,然后将那个月的天数相加,但我不确定如何正确计算它。如果我采取了错误的方法,我会很感激任何关于我应该做什么的建议?谢谢

标签: sql ms-access


【解决方案1】:

不要使用计算列,总天数,因为它汇总了几个月甚至几年的开始日期和结束日期之间的差异。考虑计算单独的持续时间:

  1. 开始日期开始日期月份结束的缺勤时间
  2. 结束日期月份的第一天到结束日期的缺勤时间

然后将聚合连接在一起。因此,例如,缺席范围 2018 年 1 月 30 日 - 2018 年 2 月 2 日:

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

开始日期查询

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

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

【讨论】:

  • 非常感谢 Parfait 的回答。恐怕我已经离开办公室几天了,所以还不能测试这个,但我一定会在我尝试过的时候做出回应。干杯
猜你喜欢
  • 2019-04-12
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
  • 2021-07-08
  • 1970-01-01
相关资源
最近更新 更多