我不确定如何进行此操作或要搜索的内容,但是在这里我尝试解释我要做什么!可能还有多种方法可以解决这个问题。
我正在开发一个“时间卡”项目,在这里我希望提取一周内未填写最短时间的所有时间卡。假设一个正常的星期是40个小时。
我还有第二张表,告诉我所有星期的结束日期。但是在大多数情况下,这是每个星期六,如果月份在周中结束,则该天是一周的结束。因此,一月我们有一个星期的结束日期为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日期加入这2个表,但有时人们在时间卡上输入错误的日期。假设他们输入1月30日至31日。因此,我无法为TSQL做一个简单的周末查找。因此,如果我加入上述两个示例,由于荷马在自己的TimeCard中输入了错误的日期,因此第31日将丢失。
我有2个问题:
是否可以找到一周结束的一周,如果该周是一个月结束的一周,它会获取“月末”日期?
如果没有,我是否可以查看周结束表,该表中包含该年的每个周末。通过获取该表中的行来进行某种日期范围的设置吗?
答案 0 :(得分:2)
如果您可以在日历表(表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