我在SQL Server中有一个名为CHECKINOUT
的表,该表包含以下列:
PASSID CHECKTIME CHECKTYPE UID
--------------------------------------------------
PS3 2015-08-05 01:12:02.100 0 CAA0322
PS3 2015-08-06 02:17:02.310 1 CAA0322
PS4 2015-08-03 01:02:03.200 0 CAA0322
PS4 2015-08-03 11:11:01.233 1 CAA0322
PS3 2015-08-02 11:11:01.210 0 CAA0322
PS3 2015-08-02 12:02:04.147 1 CAA0322
PS1 2015-09-05 11:11:01.210 0 CAA0322
PS1 2015-09-05 01:12:09.010 1 CAA0322
PASSID
是每次有人访问场所时允许的传递,当他们被允许进入时,他们的签到时间被注册并且Checktype变为0
CHECKTYPE=0
当他们结账时,他们结帐的时间也会在检查时再次登记,但这次是 checktype标志变为1
CHECKTYPE=0
现在在一天结束的时候,我希望看到每次通过的报告,无论它输入和输出的次数是多少次
PASSID CheckInTime CheckOutTime UID
PS1 2015-08-05 01:12:02.100 2015-08-06 02:17:02.310 CAA0322
PS3 2015-08-05 01:12:02.100 2015-08-06 02:17:02.310 CAA0322
PS3 2015-08-02 11:11:01.210 2015-08-02 12:02:04.147 CAA0322
PS4 2015-08-03 01:02:03.200 22015-08-03 11:11:01.233 CAA0322
以上结果显示如下
我尝试使用分区但是我失败了,我只能返回一条记录,但是我希望看到我的代码在下面的所有记录,但它只返回一条记录,我希望在不指定任何passid的情况下返回所有记录
declare @PassID varchar(30)='PS3';
with LastEntryData(PASSID, CHECKTIME, CHECKTYPE, GateID, UID)
as
(
select top 2
c.PASSID, c.CHECKTIME, c.CHECKTYPE, c.GateID, c.UID
from
CHECKINOUT c
where
c.PASSID = @PassID
order by
c.CHECKTIME desc
),
CheckInTime(CHECKTIME) as
(
select
i.CHECKTIME
from
LastEntryData i
where
i.CHECKTYPE = 0),
CheckOutTime(CHECKTIME) as
(
select
i.CHECKTIME
from
LastEntryData i
where
i.CHECKTYPE = 1)
select
l.PASSID, CheckInTime = i.CHECKTIME,
CheckOutTime = o.CHECKTIME, l.UID
from
LastEntryData l, CheckInTime i, CheckOutTime o
group by
l.PASSID, l.GateID, l.UID, i.CHECKTIME, o.CHECKTIME
答案 0 :(得分:0)
让我们做一张桌子。 (如果你这样做,你会得到更多答案。)
didFinishLaunching
我会做一些有根据的猜测,因为您的样本数据与您的预期输出不匹配。
此查询(在PostgreSQL中)返回所有检查时间。
create table checkinout (
passid char(3) not null,
checktime timestamp not null default current_timestamp,
checktype integer not null check (checktype in (1, 0)),
uid char(7) not null
);
insert into checkinout values
('PS3', '2015-08-05 01:12:02.100', 0, 'CAA0322'),
('PS3', '2015-08-06 02:17:02.310', 1, 'CAA0322'),
('PS4', '2015-08-03 01:02:03.200', 0, 'CAA0322'),
('PS4', '2015-08-03 11:11:01.233', 1, 'CAA0322'),
('PS3', '2015-08-02 11:11:01.210', 0, 'CAA0322'),
('PS3', '2015-08-02 12:02:04.147', 1, 'CAA0322'),
('PS1', '2015-09-05 11:11:01.210', 0, 'CAA0322'),
('PS1', '2015-09-05 01:12:09.010', 1, 'CAA0322');
uid passid time_in -- CAA0322 PS1 2015-09-05 11:11:01.21 CAA0322 PS3 2015-08-02 11:11:01.21 CAA0322 PS3 2015-08-05 01:12:02.1 CAA0322 PS4 2015-08-03 01:02:03.2
子查询将返回结帐时间。这将在几乎任何SQL dbms上运行。
select uid, passid, checktime as time_in
from checkinout
where checktype = 0
order by uid, passid, checktime;
uid passid time_in time_out -- CAA0322 PS1 2015-09-05 11:11:01.21 CAA0322 PS3 2015-08-02 11:11:01.21 2015-08-02 12:02:04.147 CAA0322 PS3 2015-08-05 01:12:02.1 2015-08-06 02:17:02.31 CAA0322 PS4 2015-08-03 01:02:03.2 2015-08-03 11:11:01.233
错误的数据解释了NULL。
如果您的数据和人员表现良好,并且您的平台支持分析功能,则可以使用lead()或lag()将各个部分组合在一起。 (我认为SQL Server 2012+支持lead()和lag()。)
select
t1.uid, t1.passid, t1.checktime,
(select min(checktime)
from checkinout
where uid = t1.uid
and passid = t1.passid
and checktime >= t1.checktime
and checktype = 1) as time_out
from checkinout t1
where checktype = 0
order by t1.uid, t1.passid, t1.checktime;