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