我已经阅读了很多类似的问题,但我的具体案例比我发现的大多数其他情况更简单,更复杂。这是个问题:
我有一张人工交易表,其中包含用于计时和退出的用户的日期/时间戳。每个交易(行)都有一个用户名,开始和停止时间,总小时数和一个"标签" (通常是工作单#)。
对于假期,我们为每个用户添加一个没有开始或停止时间的交易,8作为总小时数和" HOLIDAY"作为标签。我已经制作了下表的样本:
USER | STARTDATE | STARTTIME | STOPDATE | STOPTIME | HOURS | TAG
JSMITH | 7/2/12 | 9:00AM | 7/2/12 | 5:00PM | 8 | WO12345
JSMITH | 7/3/12 | 9:00AM | 7/3/12 | 5:00PM | 8 | WO13579
JSMITH | 7/4/12 | NULL | 7/4/12 | NULL | 8 | HOLIDAY
JSMITH | 7/5/12 | 9:00AM | 7/5/12 | 5:00PM | 8 | WO24680
JSMITH | 7/6/12 | 9:00AM | 7/6/12 | 5:00PM | 8 | WO98765
这是问题所在。如果用户在关键词为商业日之前的2个工作日工作,则该用户只能享受8小时的休假。休假日(可能有VACATION标签)将符合"工作"。所以基本上如果在前两天的每一天都有任何人工交易,他们就有资格度假。
为了使问题进一步复杂化,周一至周五将是一个典型的工作周,但是,人们可以在星期六工作(虽然不是必需的)所以如果假期在星期一下降,他们可以在周四/周五工作或者周五/周六有资格享受假期。
此报告每周运行一次(星期一)并查看前一周。所以我的思维过程就是你要查找带有Holiday标签的任何交易,检查2" business"每天任何交易的前几天。如果在一天或两天内未找到任何交易,则返回用户或完整假日行,以表明他们不符合条件(最终结果集应该是不符合假期的交易或用户列表)。
任何和所有帮助,无论是前2天检查还是确定"业务"天(包括可能是星期六)将非常感谢!如果您需要任何进一步的细节,也请告诉我。
谢谢!
答案 0 :(得分:0)
从这开始。
SELECT a.[STARTDATE] 'Begin Date', a.[TAG] AS 'Begin Tag',
b.[TAG] AS '1 Day Before', c.[TAG] AS '2 Days Before',
d.[TAG] AS '3 Days Before', e.[TAG] AS '4 Days Before',
f.[TAG] AS '5 Days Before'
FROM tx a
LEFT JOIN tx b ON b.[USER] = a.[USER]
AND b.[STARTDATE] = DATEADD (day, -1, a.[STARTDATE])
LEFT JOIN tx c ON c.[USER] = a.[USER]
AND c.[STARTDATE] = DATEADD (day, -2, a.[STARTDATE])
LEFT JOIN tx d ON d.[USER] = a.[USER]
AND d.[STARTDATE] = DATEADD (day, -3, a.[STARTDATE])
LEFT JOIN tx e ON e.[USER] = a.[USER]
AND e.[STARTDATE] = DATEADD (day, -4, a.[STARTDATE])
LEFT JOIN tx f ON f.[USER] = a.[USER]
AND f.[STARTDATE] = DATEADD (day, -5, a.[STARTDATE])
WHERE a.[STARTDATE] = '2012-07-05'
这将为您提供前5天(按日期)的标签:
Begin Date Begin Tag 1 Day Before 2 Days Before 3 Days Before 4 Days Before 5 Days Before ---------- --------- ------------ ------------- ------------- ------------- ------------- 2012-07-05 WO98765 WO24680 HOLIDAY WO13579 WO12345 NULL
然后,您将添加逻辑以检查前两天是否为非假日工作标记。
答案 1 :(得分:0)
这种逻辑很难以可读和高效的方式在sql中表达。 通常,我发现创建事实表更容易,因为数据太少。 这样,您就可以加入这个事实表。 我不知道你的桌子叫什么,所以我只称它为'Log'。
我相信这段代码会做你想要的。
<强>更新强>
为了允许限制星期五/星期六,而不是星期四/星期六,我修改了事实表以包括允许的组合。对于每个有效组合,给出工作日(假日)的新行和两个允许的偏移量。 对于周一(美国的工作日2),给出两对,( - 2,-3)和( - 3,-4),分别表示周五/周六和周四/周五。
新代码:
-- Create a facts table. This would maybe not be a temp table in the final solution but
-- rather a static, indexed table.
CREATE TABLE #validdays (
forday int,
validday1 int, -- offset from 'forday'
validday2 int -- offset from 'forday'
)
-- For each weekday, give the allowed combinations of work days
INSERT INTO #validdays values (2,-2,-3)
INSERT INTO #validdays values (2,-3,-4)
INSERT INTO #validdays values (6,-1,-2)
INSERT INTO #validdays values (5,-1,-2)
INSERT INTO #validdays values (4,-1,-2)
INSERT INTO #validdays values (3,-1,-3)
INSERT INTO #validdays values (3,-1,-4)
SELECT *
FROM Log l
WHERE
l.TAG = 'HOLIDAY' AND
NOT EXISTS
(SELECT *
FROM #validdays v
INNER JOIN Log vl ON vl.[USER] = l.[USER] AND
vl.startdate = DATEADD(day, v.validday1, l.startdate) AND
vl.tag <> 'HOLIDAY'
INNER JOIN Log vl2 ON vl2.[USER] = l.[USER] AND
vl2.startdate = DATEADD(day, v.validday2, l.startdate) AND
vl2.tag <> 'HOLIDAY'
WHERE v.forday = datepart(dw,l.startdate)
)
-- Any restrictions about periodicity, i.e. check that l.startdate is within last week.
drop table #validdays