SQL запрос на получение записи с максимальной датой из двух столбцов - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть SQL Таблица сервера, подобная этой:

EMPs

Id  Name    DateOn              DateOff     
-------------------------------------------------
1   EMP1    2020-9-4 12:00 AM   NULL
2   EMP1    2020-9-4 12:00 AM   2020-9-4 10:00 PM
3   EMP2    2020-7-4 12:00 AM   NULL
4   EMP4    2020-7-4 12:00 AM   2020-9-4 10:00 PM

Другой пример с запросом

DECLARE @EMP TABLE
(
    Id INT,
    NAME VARCHAR(200),
    AlarmOnTimeStamp DATETIMEOFFSET,
    AlarmOffTimeStamp DATETIMEOFFSET NULL
);


INSERT INTO @EMP VALUES(1,'Test1','2020-04-09 01:56:29.507',NULL)
INSERT INTO @EMP VALUES(2,'Test1','2020-04-09 01:56:29.507','2020-04-09 03:56:29.507')
INSERT INTO @EMP VALUES(3,'Test2','2020-04-09 01:56:29.507','2020-04-09 03:56:29.507')


select * from (
    select *,
           row_number() over (order by a.AlarmOffTimestamp  desc) rn
    from @EMP a
) a where rn = 1

введите изображение описание здесь

Id столбец уникален.

Я хочу запрос SQL, чтобы получить одну запись, как в примере выше, я должен получить Id => 2,3 и 4-я запись; Я запутался, как использовать две колонки с датами Max для группировки по заявке.

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

Я думаю, что простая row_number() функция должна быть хорошей в этом случае:

select * from (
    select *,
           row_number() over (order by DateOff desc) rn
    from myTable
) a where rn = 1

С точки зрения производительности, вы можете определить индексы для столбцов, используемых для упорядочения и фильтрации результатов, в данном случае DateOff используется для упорядочивания, поэтому это хороший кандидат на индекс.

0 голосов
/ 09 апреля 2020

Вы можете фильтровать с помощью подзапроса:

select e.*
from emps e
where e.id = (
    select top (1) id 
    from emps e1
    where e1.name = e.name 
    order by e1.dateon desc, e1.dateoff desc
)

Не очень понятно, какие критерии сортировки вы хотите; это дает вам запись, которая имеет последнюю dateon; если есть связи, dateoff используется для их разрыва. Возможно, вы захотите адаптировать условие order by подзапроса в соответствии с вашими точными требованиями.

Это решение обычно достаточно эффективно, даже для большого набора данных. Для производительности вам нужен индекс на (name, dateon, dateoff). Вы также можете попытаться добавить id в последнюю позицию в индексе, например (name, dateon, dateoff, id): это делает Inde охватывающим , что означает, что база данных может быть в состоянии выполнить подзапрос, просматривая только индекс .

Демонстрация на DB Fiddle

Пример данных:

Id | NAME  | AlarmOnTimeStamp            | AlarmOffTimeStamp          
-: | :---- | :-------------------------- | :--------------------------
 1 | Test1 | 2020-04-09 01:56:29.5070000 | <em>null</em>                       
 2 | Test1 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
 3 | Test2 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000

Результаты:

Id | NAME  | AlarmOnTimeStamp            | AlarmOffTimeStamp          
-: | :---- | :-------------------------- | :--------------------------
 2 | Test1 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
 3 | Test2 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000
...