SQL考勤查询
SQL Time Attendance Query
最近我从 MS Access 切换到 SQL 服务器。由于这个开关,我在使一个 SQL 查询工作时遇到了问题。
这就是当前 table 在 SQL 中的样子。
这是我试图从查询中得到的结果:
以前我可以通过以下查询使其在 MS Access 中工作:
SELECT m.UserEnrollNumber, m.Checktime AS TimeIn, (SELECT Min(s.Checktime)
FROM CheckInOut1 s
WHERE s.UserEnrollNumber = m.UserEnrollNumber
AND s.Checktime > m.Checktime
AND s.Checktime <= Int(m.Checktime) + 1) AS TimeOut
FROM CheckInOut1 AS m
WHERE ((((SELECT COUNT(*)
FROM CheckInOut1 s
WHERE s.UserEnrollNumber = m.UserEnrollNumber
AND s.Checktime <= m.Checktime
AND s.Checktime >= INT(m.Checktime)) Mod 2)=1));
以下查询作为@GMB 的回答:
select
employee_id,
min(time_in_out) check_in,
max(time_in_out) check_out
from (
select t.*, row_number() over(partition by employee_id order by time_in_out) - 1 rn
from mytable t
) t
group by employee_id, floor(rn / 2)
order by employee_id, floor(rn / 2)
来自 SQL table:
给我以下结果:
似乎显示了最小行和最大行,但中间的行没有显示。
来自@Gordon Linoff 的以下查询:
SELECT cio.EmployeeID, cio.TimeInOut AS CheckIn,
cio.TimeInOut as CheckOut
FROM (SELECT cio.*,
ROW_NUMBER() OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as seqnum,
LEAD(cio.TimeInOut) OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as next_TimeInOut
FROM CheckInOut22 cio
) cio
WHERE seqnum % 2 = 1;
给我以下结果:
签入与签出相同。
所有帮助将不胜感激。
这在 SQL 服务器中 简单得多。使用 window 函数:
SELECT cio.EmployeeID, cio.TimeInOut AS CheckIn,
cio.next_TimeInOut as CheckOut
FROM (SELECT cio.*,
ROW_NUMBER() OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as seqnum,
LEAD(cio.TimeInOut) OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as next_TimeInOut
FROM CheckInOut cio
) cio
WHERE seqnum % 2 = 1;
最近我从 MS Access 切换到 SQL 服务器。由于这个开关,我在使一个 SQL 查询工作时遇到了问题。
这就是当前 table 在 SQL 中的样子。
这是我试图从查询中得到的结果:
以前我可以通过以下查询使其在 MS Access 中工作:
SELECT m.UserEnrollNumber, m.Checktime AS TimeIn, (SELECT Min(s.Checktime)
FROM CheckInOut1 s
WHERE s.UserEnrollNumber = m.UserEnrollNumber
AND s.Checktime > m.Checktime
AND s.Checktime <= Int(m.Checktime) + 1) AS TimeOut
FROM CheckInOut1 AS m
WHERE ((((SELECT COUNT(*)
FROM CheckInOut1 s
WHERE s.UserEnrollNumber = m.UserEnrollNumber
AND s.Checktime <= m.Checktime
AND s.Checktime >= INT(m.Checktime)) Mod 2)=1));
以下查询作为@GMB 的回答:
select
employee_id,
min(time_in_out) check_in,
max(time_in_out) check_out
from (
select t.*, row_number() over(partition by employee_id order by time_in_out) - 1 rn
from mytable t
) t
group by employee_id, floor(rn / 2)
order by employee_id, floor(rn / 2)
来自 SQL table:
给我以下结果:
似乎显示了最小行和最大行,但中间的行没有显示。
来自@Gordon Linoff 的以下查询:
SELECT cio.EmployeeID, cio.TimeInOut AS CheckIn,
cio.TimeInOut as CheckOut
FROM (SELECT cio.*,
ROW_NUMBER() OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as seqnum,
LEAD(cio.TimeInOut) OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as next_TimeInOut
FROM CheckInOut22 cio
) cio
WHERE seqnum % 2 = 1;
给我以下结果:
签入与签出相同。
所有帮助将不胜感激。
这在 SQL 服务器中 简单得多。使用 window 函数:
SELECT cio.EmployeeID, cio.TimeInOut AS CheckIn,
cio.next_TimeInOut as CheckOut
FROM (SELECT cio.*,
ROW_NUMBER() OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as seqnum,
LEAD(cio.TimeInOut) OVER (PARTITION BY cio.EmployeeID, CONVERT(date, cio.TimeInOut) ORDER BY cio.TimeInOut) as next_TimeInOut
FROM CheckInOut cio
) cio
WHERE seqnum % 2 = 1;