【问题标题】:How to pull week ending dates and end of month when end of month is mid week当月末是周中时,如何提取周结束日期和月末
【发布时间】:2019-02-18 22:58:58
【问题描述】:

我不确定如何进行此操作或搜索什么,但我在这里尝试解释我正在尝试做什么!也可能有多种方法可以解决这个问题。

我正在做一个 Timecards 项目,我想在该项目中提取所有已填写的一周内尚未填写最短时间的时间卡。假设一个正常的一周是 40 小时。

我还有第二张表,它告诉我所有星期的结束日期。在大多数情况下,这是每个星期六,但是,如果该月在周中结束,那么那一天就是周末。所以 1 月,我们的一周结束日期是 1 月 31 日和 2 月 2 日。

其中 1 月 31 日只需要 32 小时,而 2 月 2 日则需要 8 小时。

样本数据

Week Ending Date   Minimum Hours
1/26/19             40
1/31/19             32
2/2/19              8
2/9/19              40

考勤卡示例

NAME                WeekEnding           HoursWorked
Billy Joe           1/23/19               42
Homer               1/30/19               32
Marge               1/31/19               40
Homer               2/2/19                8

理想情况下,我会在 week_ending 日期之前加入这两个表,但有时人们在考勤卡上输入的日期错误。假设他们从 1 月 30 日到 31 日。所以我不能为 TSQL 做一个简单的周末查找。因此,如果我加入上面的 2 个示例,荷马会在 31 日失踪,因为他在考勤卡中输入了错误的日期。

我有两个问题:

  1. 有没有办法找到一周的结束周,如果该周是月结束周,它会改为获取月结束日期?

  2. 如果没有,我有没有办法查看周末表,其中包含一年中的每个周末。并通过抓取该表中的行来做某种日期范围?

【问题讨论】:

    标签: sql sql-server tsql date


    【解决方案1】:

    如果您可以在日历表(表timecard)中添加一列来存储一周的开始日期,这会更简单。然后我们可以简单地聚合在每个时间间隔内提交的所有样本。

    鉴于您当前的数据库设计,一种解决方案是使用相关子查询来模拟这种行为。此后,NOT EXISTS 条件确保我们将当前的sample 记录与相关的timecard 记录连接起来。外部查询按名称和日期间隔进行聚合,HAVING BY 子句过滤未达到最小工作小时数的记录。

    SELECT
        s.name,
        s.WeekEnding DateEntered,
        t.WeekEnding,
        t.MinimumHours,
        SUM(s.HoursWorked) TotalHoursWorked
    FROM sample s
    INNER JOIN timecard t 
        ON s.WeekEnding <= t.WeekEnding
        AND NOT EXISTS (
            SELECT 1
            FROM timecard t1
            WHERE s.WeekEnding <= t.WeekEnding AND t1.WeekEnding > t.WeekEnding
        )
    GROUP BY
        s.name,
        s.WeekEnding,
        t.WeekStart,
        t.WeekEnding,        
        t.MinimumHours
    HAVING SUM(s.HoursWorked) < t.MinimumHours
    

    从 SQLServer 2017 开始,窗口函数使其变得更容易。我们可以使用LAG() 访问之前的记录:

    SELECT
        s.name,
        s.WeekEnding DateEntered,
        t.WeekStart,
        t.WeekEnding,        
        t.MinimumHours,
        SUM(s.HoursWorked) TotalHoursWorked
    FROM
        sample s
        INNER JOIN (
            SELECT 
                WeekEnding, 
                MinimumHours, 
                LAG(WeekEnding) OVER(ORDER BY WeekEnding) WeekStart
            FROM timecard
        ) t 
            ON s.WeekEnding > t.WeekStart AND s.WeekEnding <= t.WeekEnding
    GROUP BY
        s.name,
        s.WeekEnding,
        t.WeekStart,
        t.WeekEnding,        
        t.MinimumHours
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-20
      • 1970-01-01
      • 2019-09-07
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 2017-07-23
      • 1970-01-01
      相关资源
      最近更新 更多