SQL 服务器 - 如何获取根据名称和位置分组的每一天的最小和最大日期时间
SQL Server - How to get the minimum and maximum datetime for each day grouped against name and location
使用我们的门禁系统数据,我们被要求提供每天有人为每栋楼扫描卡片的最早和最晚时间。此数据需要包含员工姓名。
基本每天每栋楼的先进后出
例如:
+-------------------------+--------------+------------+
| Scantime | Staff | Building |
+-------------------------+--------------+------------+
| 2018-06-01 05:13:27.000 | Joe Bloggs | Building 1 |
| 2018-06-01 05:30:19.000 | Mary Sue | Building 2 |
| 2018-06-01 05:42:44.000 | Pete Generic | Building 3 |
| 2018-06-01 05:47:46.000 | Pete Generic | Building 4 |
| 2018-06-01 16:30:35.000 | Joe Bloggs | Building 1 |
| 2018-06-01 16:46:49.000 | John Generic | Building 2 |
| 2018-06-01 16:58:11.000 | Joe Bloggs | Building 4 |
| 2018-06-01 17:14:15.000 | Joe Bloggs | Building 3 |
+-------------------------+--------------+------------+
我们在以下查询中取得了一些成功:
SELECT ScanTime, Staff, Building
FROM dbo.SentryJuno$ AS t1
WHERE (ScanTime IN
(SELECT MIN(ScanTime) AS Expr1
FROM dbo.SentryJuno$
GROUP BY CONVERT(date, TimeStamp), Building)) OR
(ScanTime IN
(SELECT MAX(ScanTime) AS Expr1
FROM dbo.SentryJuno$ AS SentryJuno$_1
GROUP BY CONVERT(date, ScanTime), Building))
此查询的问题在于,如果数据中有任何相同的 timestamps/scantimes,则两者都会 returns。
我们是否可以提高此查询的准确性?
SELECT Staff, Building,
CAST(ScanTime AS DATE) AS ScanDate,
MIN(ScanTime) AS FirstScanTime,
MAX(ScanTime) AS LastScanTime
FROM dbo.[SentryJuno$]
GROUP BY Staff, Building, CAST(ScanTime AS DATE);
或者查看您的查询,您可能要求:
SELECT Staff, Building,
CAST(ScanTime AS DATE) AS ScanDate,
MIN(ScanTime) AS ScanTime
FROM dbo.[SentryJuno$]
GROUP BY Staff, Building, CAST(ScanTime AS DATE)
UNION
SELECT Staff, Building,
CAST(ScanTime AS DATE) AS ScanDate,
MAX(ScanTime) AS ScanTime
FROM dbo.[SentryJuno$]
GROUP BY Staff, Building, CAST(ScanTime AS DATE)
编辑:您的问题不清楚,阅读评论也许您正在问这个?:
SELECT *
FROM dbo.SentryJuno$ s
INNER JOIN(
SELECT Building, CAST(Scantime AS DATE) AS ScanDate, MIN(Scantime) AS ScanTime
FROM dbo.SentryJuno$
GROUP BY Building, CAST(Scantime AS DATE)
UNION
SELECT Building, CAST(Scantime AS DATE) AS ScanDate, MAX(Scantime) AS ScanTime
FROM dbo.SentryJuno$
GROUP BY Building, CAST(Scantime AS DATE)
) fl ON fl.Building=s.Building
AND fl.ScanTime=s.Scantime;
with cte as(
SELECT t1.Scantime,
t1.Staff,
t1.Building,
row_number() over (PARTITION BY CAST(t1.Scantime AS DATE), t1.Building ORDER BY t1.Scantime ASC) RNF,
row_number() OVER (PARTITION BY CAST(t1.Scantime AS DATE), t1.Building ORDER BY t1.Scantime DESC) RNL
FROM dbo.SentryJuno$ AS t1
)
SELECT DQ.Scantime,DQ.staff, DQ.Building (select * from CTE where CTE.RNF = 1 UNION select * from CTE where CTE.RNL = 1) DQ
ORDER BY DQ.Scantime
使用我们的门禁系统数据,我们被要求提供每天有人为每栋楼扫描卡片的最早和最晚时间。此数据需要包含员工姓名。
基本每天每栋楼的先进后出
例如:
+-------------------------+--------------+------------+
| Scantime | Staff | Building |
+-------------------------+--------------+------------+
| 2018-06-01 05:13:27.000 | Joe Bloggs | Building 1 |
| 2018-06-01 05:30:19.000 | Mary Sue | Building 2 |
| 2018-06-01 05:42:44.000 | Pete Generic | Building 3 |
| 2018-06-01 05:47:46.000 | Pete Generic | Building 4 |
| 2018-06-01 16:30:35.000 | Joe Bloggs | Building 1 |
| 2018-06-01 16:46:49.000 | John Generic | Building 2 |
| 2018-06-01 16:58:11.000 | Joe Bloggs | Building 4 |
| 2018-06-01 17:14:15.000 | Joe Bloggs | Building 3 |
+-------------------------+--------------+------------+
我们在以下查询中取得了一些成功:
SELECT ScanTime, Staff, Building
FROM dbo.SentryJuno$ AS t1
WHERE (ScanTime IN
(SELECT MIN(ScanTime) AS Expr1
FROM dbo.SentryJuno$
GROUP BY CONVERT(date, TimeStamp), Building)) OR
(ScanTime IN
(SELECT MAX(ScanTime) AS Expr1
FROM dbo.SentryJuno$ AS SentryJuno$_1
GROUP BY CONVERT(date, ScanTime), Building))
此查询的问题在于,如果数据中有任何相同的 timestamps/scantimes,则两者都会 returns。
我们是否可以提高此查询的准确性?
SELECT Staff, Building,
CAST(ScanTime AS DATE) AS ScanDate,
MIN(ScanTime) AS FirstScanTime,
MAX(ScanTime) AS LastScanTime
FROM dbo.[SentryJuno$]
GROUP BY Staff, Building, CAST(ScanTime AS DATE);
或者查看您的查询,您可能要求:
SELECT Staff, Building,
CAST(ScanTime AS DATE) AS ScanDate,
MIN(ScanTime) AS ScanTime
FROM dbo.[SentryJuno$]
GROUP BY Staff, Building, CAST(ScanTime AS DATE)
UNION
SELECT Staff, Building,
CAST(ScanTime AS DATE) AS ScanDate,
MAX(ScanTime) AS ScanTime
FROM dbo.[SentryJuno$]
GROUP BY Staff, Building, CAST(ScanTime AS DATE)
编辑:您的问题不清楚,阅读评论也许您正在问这个?:
SELECT *
FROM dbo.SentryJuno$ s
INNER JOIN(
SELECT Building, CAST(Scantime AS DATE) AS ScanDate, MIN(Scantime) AS ScanTime
FROM dbo.SentryJuno$
GROUP BY Building, CAST(Scantime AS DATE)
UNION
SELECT Building, CAST(Scantime AS DATE) AS ScanDate, MAX(Scantime) AS ScanTime
FROM dbo.SentryJuno$
GROUP BY Building, CAST(Scantime AS DATE)
) fl ON fl.Building=s.Building
AND fl.ScanTime=s.Scantime;
with cte as(
SELECT t1.Scantime,
t1.Staff,
t1.Building,
row_number() over (PARTITION BY CAST(t1.Scantime AS DATE), t1.Building ORDER BY t1.Scantime ASC) RNF,
row_number() OVER (PARTITION BY CAST(t1.Scantime AS DATE), t1.Building ORDER BY t1.Scantime DESC) RNL
FROM dbo.SentryJuno$ AS t1
)
SELECT DQ.Scantime,DQ.staff, DQ.Building (select * from CTE where CTE.RNF = 1 UNION select * from CTE where CTE.RNL = 1) DQ
ORDER BY DQ.Scantime