我有一个存储过程,用于检索员工每日摘要及时:
SELECT ads.attendancesumid,
ads.employeeid,
ads.date,
ads.day, -- month day number
ads.intime,
ads.outtime
--employee shift intime and outtime
ss.intime,
ss.outtime
FROM employee_attendance_daily_summary ads
JOIN employee emp
ON emp.employeeid = ads.employeeid
JOIN setup_shift ss
ON ss.shiftcode = emp.shiftcode
AND DATEPART(dw, ads.date) = ss.day
WHERE ads.employeeid = 4 -- just to filter one employee
查询结果如下:
每个day
重复 3次,因为表setup_shift
(员工轮班)有:
周一至周日有3种不同的班次类型: DAY , AFTERNOON 和 NIGHT 。
以下是相同的信息,但使用班次类型列:
我需要的是仅每天获得1行,但最近的员工班次取决于
intime
和outtime
。
所以欲望结果应该是这样的:
有关如何做到这一点的任何线索?提前欣赏它。
我还有intime
00:00:00
但outtime
有值的情况:
更新
这里是SQL FIDDLE
答案 0 :(得分:0)
如果时间是在午夜之后的几秒钟内,而不是time
,datetime
或字符串格式,则会更容易。您可以使用以下公式转换它们:
select datepart(hour, intime) * 3600 + datepart(minute, intime) * 60 + datepart(second, intime)
(部分原因是我对处理其他数据类型所需的所有嵌套函数感到不舒服。)
所以,让我假设您有一系列类似的列,以秒为单位。然后,您可以通过对每个班次进行重叠并选择具有最大重叠的班次来解决此问题。
with t as (
<your query here>
),
ts as (
select t.*,
(datepart(hour, ads.intime) * 3600 + datepart(minute, ads.intime) * 60 +
datepart(second, ads.intime)
) as e_intimes,
. . .
from t
),
tss as (
select ts.*,
(case when e_intimes >= s_outtimes then 0
when e_outtimes <= s_inttimes then 0
else (case when e_outtimes < s_outtimes then e_outtimes else s_outtimes end) -
(case when e_intimes > s_intimes then e_intimes else s_intimes end)
end) as overlap
from ts
)
select ts.*
from (select ts.*,
row_number() over (partition by employeeid, date
order by overlap desc
) as seqnum
from ts
) ts
where seqnum = 1;
答案 1 :(得分:0)
select ads.attendancesumid,
ads.employeeid,
ads.date,
ads.day,
ads.intime,
ads.outtime,
ss.intime,
ss.outtime
from employee_attendance_daily_summary ads
join employee emp
on emp.employeeid = ads.employeeid
join setup_shift ss
on ss.shiftcode = emp.shiftcode
and datepart(dw, ads.date) = ss.day
where ads.employeeid = 4
and ((abs(datediff(hh,
cast(ads.intime as datetime),
cast(ss.intime as datetime))) between 0 and 2) or
(ads.intime = '00:00:00' and
ss.intime =
(select min(x.intime)
from setup_shift x
where x.shiftcode = ss.shiftcode
and x.intime > (select min(y.intime)
from setup_shift y
where y.shiftcode = x.shiftcode))))
答案 2 :(得分:0)
试试这个男人,我只考虑每组datediff(mi,intime,shift_intime)
Select * from
(select
row_number() over(partition by employeeid
order by datediff(mi,intime,shift_intime) asc) as id,
attendance,employeeid,date,day,intime,outime,shiftintime,shiftoutime from table
)
where id=1