我有一个查询,抓住第一个打孔的部门中的第一个人,以及最后打了一个部门的人。基本上,这显示我打开了一个位置,并关闭了一个位置。下面是我的查询我正在使用“OVER”函数,但是over函数对VB.net中的数据集不起作用是否还有其他选项来替换over函数?
SELECT * FROM (
SELECT timeclock.dtTimeIn, timeclock.dtTimeOut, employees.sfirstname,
RANK() OVER ( ORDER BY dtTimeIn) rk1, --earliest record gets 1
RANK() OVER (ORDER BY dtTimeOut DESC) rk2 --latest record gets 1
FROM TimeClock INNER JOIN
Employees ON TimeClock.lEmployeeID = Employees.lEmployeeID
WHERE (dtTimeIn > dateadd(day, datediff(day, 0, getdate())-1, 0)) AND (dtTimeOut < dateadd(day, datediff(day, 0, getdate()), 0)) AND
(sDept IN ('1', '2', '3'))
) A
WHERE rk2=1
答案 0 :(得分:2)
您可以将其替换为相关子查询。以下是rk1
的示例:
(select count(distinct lEmployeeId)
from TimeClock tc
where tc.lEmployeeId = timeclock.lemployeeId and
tc.dtTimeIn <= timeclock.dtTimeIn
) as rk1
Rank可以生成多个标记为1的记录(当存在关联时)。如果你的意思是row_number()
,那么你可以在上面的查询中使用count(*)
而不是count(distinct)
。
答案 1 :(得分:2)
你可以试试这个:
SELECT tc.dtTimeIn
, tc.dtTimeOut
, e.sfirstname
FROM TimeClock tc
JOIN Employees e ON tc.lEmployeeID = e.lEmployeeID
JOIN (
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, tc.dtTimeIn), 0) _date
, MIN(tc.dtTimeIn) dtTimeIn
, MAX(tc.dtTimeOut) dtTimeOut
FROM TimeClock tc
WHERE e.sDept IN ('1', '2', '3')
GROUP BY
DATEADD(DAY, DATEDIFF(DAY, 0, tc.dtTimeIn), 0)
) t ON t._date = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
AND DATEADD(DAY, DATEDIFF(DAY, 0, tc.dtTimeIn), 0) = t._date
AND (t.dtTimeIn = tc.dtTimeIn OR t.dtTimeOut = tc.dtTimeOut)
WHERE e.sDept IN ('1', '2', '3')
答案 2 :(得分:1)
您的查询只返回关闭某个位置的人...
返回谁打开以及谁关闭你需要将你的where子句更改为
where rk2 = 1 or rk1 = 1
如果您同时从多个sDept获取订单,则应按顺序对sDept进行分区
RANK() OVER ( partition by sDept ORDER BY dtTimeIn) rk1, --earliest record gets 1
RANK() OVER ( partition by sDept ORDER BY dtTimeOut DESC) rk2 --latest record get
...见
设置环境以运行查询
declare @TimeClock table ( lEmployeeID int, dtTimeIn datetime, dtTimeOut datetime)
declare @Employees table ( lEmployeeID int, sfirstname varchar(max),sDept varchar(max))
declare @getDate date
set @getDate ='02/12/2013'
insert @Employees
values (1,'Ana','1')
,(2,'Pedro','1')
,(3,'Alfred','2')
insert @TimeClock
values (1 ,'02/12/2013 08:30','02/11/2013 11:30')
,(2 ,'02/12/2013 08:00','02/11/2013 11:00')
,(3 ,'02/12/2013 08:15','02/11/2013 11:15')
您的查询...
SELECT * FROM (
SELECT timeclock.dtTimeIn, timeclock.dtTimeOut, employees.sfirstname,
RANK() OVER (partition by sDept ORDER BY dtTimeIn) rk1, --earliest record gets 1
RANK() OVER (partition by sDept ORDER BY dtTimeOut DESC) rk2 --latest record gets 1
FROM @TimeClock timeclock
INNER JOIN @Employees Employees
ON TimeClock.lEmployeeID = Employees.lEmployeeID
WHERE (dtTimeIn > dateadd(day, datediff(day, 0, @getDate)-1, 0)) AND (dtTimeOut < dateadd(day, datediff(day, 0, @getDate), 0)) AND
(sDept IN ('1', '2', '3'))
) A
WHERE rk2=1
...返回
dtTimeIn dtTimeOut sfirstname rk1 rk2
2013-02-12 08:30:00.000 2013-02-11 11:30:00.000 Ana 3 1
请参阅..关闭的是谁在结果集
更改where子句......
SELECT * FROM (
SELECT timeclock.dtTimeIn, timeclock.dtTimeOut, employees.sfirstname,
RANK() OVER ( ORDER BY dtTimeIn) rk1, --earliest record gets 1
RANK() OVER (ORDER BY dtTimeOut DESC) rk2 --latest record gets 1
FROM @TimeClock timeclock
INNER JOIN @Employees Employees
ON TimeClock.lEmployeeID = Employees.lEmployeeID
WHERE (dtTimeIn > dateadd(day, datediff(day, 0, @getDate)-1, 0)) AND (dtTimeOut < dateadd(day, datediff(day, 0, @getDate), 0)) AND
(sDept IN ('1', '2', '3'))
) A
WHERE rk2=1
or rk1 = 1
返回...谁打开谁关闭...
dtTimeIn dtTimeOut sfirstname rk1 rk2
2013-02-12 08:30:00.000 2013-02-11 11:30:00.000 Ana 3 1
2013-02-12 08:00:00.000 2013-02-11 11:00:00.000 Pedro 1 3
2013-02-12 08:15:00.000 2013-02-11 11:15:00.000 Alfred 1 1
Pedro确实打开了,Ana关闭了sDept'1'并且Alfred确实打开并关闭了sDept'2'