我有一张表Access
:
logId empid empname inout tim
----------------------------------------------------
230361 0100 XYZ 0 2015-08-01 10:00:03
230362 0106 XYZ 0 2015-08-01 10:30:00
230363 0100 XYZ 1 2015-08-01 12:00:00
记录每位员工的及时和时间。 inout=0
表示在inout=1
表示
我想从此表中创建如下表格
empid empname timIn timOut
-------------------------------------------------------------
0100 XYZ 2015-08-01 10:00:03 2015-08-01 12:00:00
0106 XYZ 2015-08-01 10:30:00
首先,我尝试了以下案例:
select
empid, empname, inout,
case when inout = 0 then tim end as 'timIn',
case when inout = 1 then tim end as 'timout'
但是NULL结果是
的问题0100 xyz 2015-08-01 10:00:03 NULL
0100 xyz NULL 2015-08-01 12:00:00
其次我试过PIVOT
,但问题是我必须使用聚合函数。我需要所有的进出时间,不能总结。
有没有其他方法可以获得所需的结果?
答案 0 :(得分:3)
您可以将APPLY
与TOP 1
和正确的ORDER BY
结合使用,以便在事件发生后获得下一个事件
SELECT i.empID,
i.empname,
TimeIn = i.tim,
TimeOut = o.tim
FROM Access AS i
OUTER APPLY
( SELECT TOP 1 tim
FROM Access AS o
WHERE o.EmpID = i.EmpID
AND o.InOut = 1
AND o.tim > i.tim
ORDER BY o.Tim
) AS o
WHERE i.InOut = 0;
因此,您只需选择所有in
个事件(表别名i
),然后针对每个in
事件,找到下一个out
事件,如果没有,那么超时字段将为空。
完整的工作示例
DECLARE @Access TABLE (LogID INT NOT NULL, EmpID CHAR(4) NOT NULL, empname VARCHAR(50), InOut BIT NOT NULL, tim DATETIME2 NOT NULL);
INSERT @Access (LogID, EmpID, empname, InOut, tim)
VALUES
(230361, '0100', 'XYZ', 0, '2015-08-01 10:00:03'),
(230362, '0106', 'XYZ', 0, '2015-08-01 10:30:00'),
(230363, '0100', 'XYZ', 1, '2015-08-01 12:00:00');
SELECT i.empID,
i.empname,
TimeIn = i.tim,
TimeOut = o.tim
FROM @Access AS i
OUTER APPLY
( SELECT TOP 1 tim
FROM @Access AS o
WHERE o.EmpID = i.EmpID
AND o.InOut = 1
AND o.tim > i.tim
ORDER BY o.Tim
) AS o
WHERE i.InOut = 0;
答案 1 :(得分:1)
更新:根据评论,我应该改进此查询以获取所有日期数据,而不仅仅是上次日期的数据,更新后的查询只包含新的日期列
select empid,empname,d,[0] as [timin],[1] as [timOut]
from
(select empid,empname, cast(tim as DATE)as d,inout,tim from tbl) s
pivot
(max(tim) for inout in ([0],[1]))p
更新了小提琴链接http://sqlfiddle.com/#!6/f1bc7/1
尝试
PIVOT
这样的查询:select empid,empname,[0] as [timin],[1] as [timOut] from (select empid,empname,inout,tim from tbl) s pivot (max(tim) for inout in ([0],[1]))p
添加了SQL小提琴链接http://sqlfiddle.com/#!6/6c3bf/1
答案 2 :(得分:1)
所以我认为你想做的是每次进入后第一次找到。下面的SQL应该这样做。
Select
empid,
empname,
tim as timein
(select top 1 tim
from my_table outTimes
where outTimes.inout = 1 and
outTimes.empid = inTimes.empid and
outTimes.tim > inTimes.tim
orderby outTimes.tim asc
) as timeout
from my_table inTimes
when inout=0
这里的关键位是orderby asc和top 1.这是下一次在桌面上给你的东西。