这是我的桌子:
date time
6/24/2018 13:42:21
6/24/2018 22:43:42
6/26/2018 9:32:41
6/26/2018 14:45:32
6/27/2018 15:04:21
6/27/2018 19:05:44
6/28/2018 2:03:44
6/28/2018 4:05:44
6/28/2018 15:05:44
6/28/2018 20:03:32
6/29/2018 9:04:06
6/29/2018 21:06:32
6/30/2018 4:50:33
6/30/2018 14:44:33
6/30/2018 21:33:44
它描述了人们进入建筑物的时间和日期,我需要这样的表格:
arrival date arrival time leaving date leaving time
6/24/2018 13:42:21 6/24/2018 22:43:42
6/26/2018 9:32:41 6/26/2018 14:45:32
6/27/2018 15:04:21 6/28/2018 4:05:44
6/28/2018 15:05:44 6/28/2018 20:03:32
6/29/2018 9:04:06 6/30/2018 4:50:33
6/30/2018 14:44:33 6/30/2018 21:33:44
真正的问题是,如果有人在早上00到04之间退出buildig,则需要在表中作为离开时间
我尝试过:
SELECT t1.tfullname,
t1.arrival_date,
ks.arrival_time_new,
t1.leaving_date,
t1.leaving_time
FROM (SELECT MIN(arrival_day) AS arrival_time_new,
arrival_date,
tFullName
FROM dbo.DB
WHERE DATEPART(hh, arrival_day) NOT BETWEEN 00 AND 05
GROUP BY arrival_date,
tFullName) ks
JOIN (SELECT tFullName,
arrival_date,
MIN(arrival_day) AS arrival_time,
MAX(leaving_day) AS leaving_time,
CASE
WHEN LEAD(DATEPART(hh, MIN(arrival_day)), 1, 0) OVER (ORDER BY tfullname) BETWEEN 00 AND 04 THEN LEAD(leaving_date, 1, leaving_date) OVER (ORDER BY tfullname)
ELSE leaving_date
END AS leaving_date,
CASE
WHEN LEAD(DATEPART(hh, MIN(arival_day)), 1, 0) OVER (ORDER BY arrival_date) BETWEEN 00 AND 04 THEN LEAD((SELECT MAX(leaving_day) AS leaving_time
FROM dbo.db
WHERE DATEPART(hh, arival_day) BETWEEN 00 AND 05
GROUP BY leaving_date,
arrival_date),
1,
MAX(leaving_day)) OVER (ORDER BY arrival_date)
ELSE MAX(leaving_day)
END AS leaving_time
FROM dbo.DB
GROUP BY arrival_date,
leaving_date,
tFullName) t1 ON t1.arrival_date = ks.arrival_date
ORDER BY DATEPART(yy, t1.arrival_date),
t1.arrival_date;
它导致了这个问题:
SQL Server子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =时,不允许这样做 例如,另外2个tble:
输入
names date time
Shh 6/6/2018 10:24
Iii 6/6/2018 10:34
Rrr 6/6/2018 10:55
Shh 6/6/2018 21:34
Iii 6/6/2018 22:34
Rrr 6/6/2018 22:55
Rrr 6/7/2018 3:34
输出
names arrival date arrival time leaving_date leaving time
Shh 6/6/2018 10:24 6/6/2018 21:34
Iii 6/6/2018 10:34 6/6/2018 22:34
Rrr 6/6/2018 10:55 6/7/2018 3:34
我该如何解决这个问题?
答案 0 :(得分:2)
非常复杂。这是一个快速的答案...将尝试处理优化的查询。
但是结果符合您的预期
;WITH cte AS(
SELECT date,
time,
DATEADD(MINUTE,-299,CONVERT(DATETIME,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108))) AS Col3,
ROW_NUMBER() OVER(PARTITION BY
CONVERT(DATE,DATEADD(MINUTE,-299,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108)))
ORDER BY DATEADD(MINUTE,-299,CONVERT(DATETIME,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108)))
) AS RN,
ROW_NUMBER() OVER(PARTITION BY
CONVERT(DATE,DATEADD(MINUTE,-299,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108)))
ORDER BY DATEADD(MINUTE,-299,CONVERT(DATETIME,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108))) DESC
) AS RN1,
CONVERT(DATE,DATEADD(MINUTE,-299,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108))) AS Date1
FROM Table1
)
SELECT DISTINCT
T1.date AS [arrival date],T1.time AS [arrival time],
T2.date AS [leaving date],T2.time AS [leaving time]
FROM cte AS T1
INNER JOIN cte AS T2
ON T1.Date1=T2.Date1
WHERE T1.RN=1
AND T2.RN1=1
-问题更改后编辑:
;WITH cte AS(
SELECT names,
date,
time,
DATEADD(MINUTE,-299,CONVERT(DATETIME,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108))) AS Col3,
ROW_NUMBER() OVER(PARTITION BY
names,CONVERT(DATE,DATEADD(MINUTE,-299,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108)))
ORDER BY DATEADD(MINUTE,-299,CONVERT(DATETIME,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108)))
) AS RN,
ROW_NUMBER() OVER(PARTITION BY
names,CONVERT(DATE,DATEADD(MINUTE,-299,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108)))
ORDER BY DATEADD(MINUTE,-299,CONVERT(DATETIME,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108))) DESC
) AS RN1,
CONVERT(DATE,DATEADD(MINUTE,-299,CONVERT(VARCHAR(100),date,112)+' '+CONVERT(VARCHAR(100),time,108))) AS Date1
FROM Table2
)
SELECT DISTINCT
T1.names,
T1.date,T1.time,
T2.date,T2.time
FROM cte AS T1
INNER JOIN cte AS T2
ON T1.Date1=T2.Date1
AND T1.names=T2.names
WHERE T1.RN=1
AND T2.RN1=1
ORDER BY T1.date
答案 1 :(得分:1)
似乎行的语义(是在行中还是在行中)完全取决于date
和time
排序的位置。如果是这样,那应该可以使用row_number()
和模2来解决(因为第二行(按顺序)是out记录)。也就是说,将行号模2为1的所有行与行号等于另一行的行号加1的行连接起来。
WITH cte
AS
(
SELECT date,
time,
row_number() OVER (ORDER BY date,
time) rn;
FROM elbat
)
SELECT cte1.date [arrival date],
cte1.time [arrival time],
cte2.date [leaving date],
cte2.time [leaving time]
FROM (SELECT cte.date,
cte.time,
cte.rn
FROM cte
WHERE cte.rn % 2 = 1) cte1
LEFT JOIN cte cte2
ON cte2.rn = cte1.rn + 1;