SQL Server - Как получить минимальную и максимальную дату и время для каждого дня, сгруппированные по имени и местоположению - PullRequest
0 голосов
/ 04 июля 2018

Используя данные нашей системы доступа к двери, нас попросили указать самое раннее и самое позднее время, когда кто-нибудь сканирует карту для каждого здания. Эти данные должны включать имя сотрудника.

В основном, первый и последний из каждого здания каждый день.

Например:

+-------------------------+--------------+------------+
|        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))

Проблема с этим запросом заключается в том, что если в данных есть какие-либо идентичные метки времени / времени сканирования, он возвращает оба.

Можно ли как-нибудь улучшить точность этого запроса?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018
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
0 голосов
/ 04 июля 2018
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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...