如何获取这些数据?
How to get this data?
我有这样的东西:
Time EQID STATUS USER
12:12am EQ1 0 SA
12:14am EQ1 1 SA
02:30am EQ2 0 SA
03:30am EQ2 1 SA
05:30am EQ1 0 SA
06:30am EQ2 1 SA
现在要求的输出是:
In_time Out_time EQID USER
12:12am 12:14am EQ1 SA
02:30am 03:30am EQ2 SA
05:30am 06:30am EQ1 SA
此处In_time
是状态为“0”的时间,Out_time
是状态为“1”的时间。我怎样才能为那个特定的 EQID 和用户得到这个 In_time
和 Out_time
。
注意:像这样我有很多行有多个用户,我怎样才能得到这个?
一种方法是对 Status=0 的所有行执行主查询。这将为您提供除 out_time
.
之外的所有列
添加一个相关的子查询来获取out_time
并获取第一行(按Time
排序)其中EQID和User与主查询相同,status=1 ,并且 Time
大于主查询中的 Time
。
(换句话说,out_Time
是此 EQID 和状态为 1 的用户的 MIN Time
,它大于当前状态=0 行。)
CREATE TABLE #data (
[Time] datetime,
[EQID] nvarchar(10),
[Status] bit,
[User] nvarchar(10)
)
INSERT INTO #data VALUES ('2017-12-27 12:12am', 'EQ1', 0, 'SA')
INSERT INTO #data VALUES ('2017-12-27 12:14am', 'EQ1', 1, 'SA')
INSERT INTO #data VALUES ('2017-12-27 02:30am', 'EQ1', 0, 'SA')
INSERT INTO #data VALUES ('2017-12-27 03:30am', 'EQ1', 1, 'SA')
INSERT INTO #data VALUES ('2017-12-27 05:30am', 'EQ1', 0, 'SA')
INSERT INTO #data VALUES ('2017-12-27 06:30am', 'EQ1', 1, 'SA')
-- Get the next time where status is 1
SELECT D1.[Time] as 'In_Time'
, D2.[Time] as 'Out_Time'
, D1.[EQID]
, D1.[User]
FROM #data D1
LEFT JOIN #data D2
ON D2.[Time] = (SELECT TOP 1 [Time]
FROM #data
WHERE [Status] = 1
AND [Time] > D1.[Time]
AND [User] = D1.[User]
AND [EQID] = D1.[EQID]
ORDER BY [Time])
WHERE D1.[Status] = 0
你这里有一些问题。
- 您正在将
TIME
存储为 VARCHAR
- 您正在存储没有
DATE
的 TIME,这使得无法确定用户在某一天签到但在下一天没有签出
- 你没有提到 EQID 是什么,或者你为什么在最后一行选择 EQ1 而不是 EQ2
话虽这么说...这是一种方法。
declare @table table ( [Time] varchar(64),
EQID char(3),
[STATUS] int,
[USER] char(2))
insert into @table
values
('12:12am','EQ1',0,'SA'),
('12:14am','EQ1',1,'SA'),
('02:30am','EQ2',0,'SA'),
('03:30am','EQ2',1,'SA'),
('05:30am','EQ1',0,'SA'),
('06:30am','EQ2',1,'SA')
;with cte as(
select
[Time]
,EQID
,[USER]
,[Status]
,RN = row_number() over(partition by [USER] order by cast(stuff([Time],6,0,' ') as time))
from
@table t)
select
In_Time = i.[Time]
,Out_Time = o.[Time]
,i.EQID
,i.[USER]
from
cte i
left join cte o on
o.[USER] = i.[USER]
and o.RN = i.RN + 1
where
i.[STATUS] = 0
我有这样的东西:
Time EQID STATUS USER
12:12am EQ1 0 SA
12:14am EQ1 1 SA
02:30am EQ2 0 SA
03:30am EQ2 1 SA
05:30am EQ1 0 SA
06:30am EQ2 1 SA
现在要求的输出是:
In_time Out_time EQID USER
12:12am 12:14am EQ1 SA
02:30am 03:30am EQ2 SA
05:30am 06:30am EQ1 SA
此处In_time
是状态为“0”的时间,Out_time
是状态为“1”的时间。我怎样才能为那个特定的 EQID 和用户得到这个 In_time
和 Out_time
。
注意:像这样我有很多行有多个用户,我怎样才能得到这个?
一种方法是对 Status=0 的所有行执行主查询。这将为您提供除 out_time
.
添加一个相关的子查询来获取out_time
并获取第一行(按Time
排序)其中EQID和User与主查询相同,status=1 ,并且 Time
大于主查询中的 Time
。
(换句话说,out_Time
是此 EQID 和状态为 1 的用户的 MIN Time
,它大于当前状态=0 行。)
CREATE TABLE #data (
[Time] datetime,
[EQID] nvarchar(10),
[Status] bit,
[User] nvarchar(10)
)
INSERT INTO #data VALUES ('2017-12-27 12:12am', 'EQ1', 0, 'SA')
INSERT INTO #data VALUES ('2017-12-27 12:14am', 'EQ1', 1, 'SA')
INSERT INTO #data VALUES ('2017-12-27 02:30am', 'EQ1', 0, 'SA')
INSERT INTO #data VALUES ('2017-12-27 03:30am', 'EQ1', 1, 'SA')
INSERT INTO #data VALUES ('2017-12-27 05:30am', 'EQ1', 0, 'SA')
INSERT INTO #data VALUES ('2017-12-27 06:30am', 'EQ1', 1, 'SA')
-- Get the next time where status is 1
SELECT D1.[Time] as 'In_Time'
, D2.[Time] as 'Out_Time'
, D1.[EQID]
, D1.[User]
FROM #data D1
LEFT JOIN #data D2
ON D2.[Time] = (SELECT TOP 1 [Time]
FROM #data
WHERE [Status] = 1
AND [Time] > D1.[Time]
AND [User] = D1.[User]
AND [EQID] = D1.[EQID]
ORDER BY [Time])
WHERE D1.[Status] = 0
你这里有一些问题。
- 您正在将
TIME
存储为VARCHAR
- 您正在存储没有
DATE
的 TIME,这使得无法确定用户在某一天签到但在下一天没有签出 - 你没有提到 EQID 是什么,或者你为什么在最后一行选择 EQ1 而不是 EQ2
话虽这么说...这是一种方法。
declare @table table ( [Time] varchar(64),
EQID char(3),
[STATUS] int,
[USER] char(2))
insert into @table
values
('12:12am','EQ1',0,'SA'),
('12:14am','EQ1',1,'SA'),
('02:30am','EQ2',0,'SA'),
('03:30am','EQ2',1,'SA'),
('05:30am','EQ1',0,'SA'),
('06:30am','EQ2',1,'SA')
;with cte as(
select
[Time]
,EQID
,[USER]
,[Status]
,RN = row_number() over(partition by [USER] order by cast(stuff([Time],6,0,' ') as time))
from
@table t)
select
In_Time = i.[Time]
,Out_Time = o.[Time]
,i.EQID
,i.[USER]
from
cte i
left join cte o on
o.[USER] = i.[USER]
and o.RN = i.RN + 1
where
i.[STATUS] = 0