Последняя запись в группе SQL Сервер - PullRequest
1 голос
/ 28 марта 2020

Учитывая приведенные ниже примеры данных, мне нужен список идентификаторов, последняя запись которых отклонена. Таким образом, мне нужно увидеть идентификатор 2, потому что его последняя версия 6/4/2020, и это отклонено. Я не хочу видеть идентификатор 1, так как его последняя запись запрашивается.

CREATE TABLE #temp
(
    id int, 
    mydate datetime,
    status VARCHAR(20)
)

INSERT INTO #temp VALUES (1, '6/1/2020', 'Rejected')
INSERT INTO #temp VALUES (1, '6/2/2020', 'Requested')
INSERT INTO #temp VALUES (1, '6/3/2020', 'Rejected')
INSERT INTO #temp VALUES (1, '6/4/2020', 'Requested')

INSERT INTO #temp VALUES (2, '6/1/2020', 'Requested')
INSERT INTO #temp VALUES (2, '6/2/2020', 'Requested')
INSERT INTO #temp VALUES (2, '6/3/2020', 'Requested')
INSERT INTO #temp VALUES (2, '6/4/2020', 'Rejected')

SELECT * FROM #temp

SELECT id, MAX(mydate)
FROM #temp
WHERE status = 'Rejected'
GROUP BY id

Это моя попытка patheti c до сих пор

SELECT id, MAX(mydate)
FROM #temp
WHERE status = 'Rejected'
GROUP BY id

Но это только вернет последняя дата в каждой группе. Мне нужен список, где последняя запись была отклонена. Я ожидаю, что ответ будет смущающе простым, но у меня чертовски много времени с этим.

Спасибо

Карл

Ответы [ 2 ]

1 голос
/ 28 марта 2020

Вы можете получить это, используя функцию row_number(), как показано ниже.

;WITH cte
AS (
    SELECT Id
        ,mydate
        ,STATUS
        ,ROW_NUMBER() OVER (
            PARTITION BY Id, status ORDER BY mydate desc
            ) row_num
    FROM #temp
    )
SELECT *
FROM cte
WHERE row_num = 1
    AND STATUS = 'Rejected'

Вот живое db <> fiddle demo.

1 голос
/ 28 марта 2020

Один метод использует агрегацию и having:

select id
from #temp
group by id
having max(case when status = 'Rejected' then mydate end) = max(mydate);

Это почти прямой перевод вашего вопроса: самая поздняя дата для 'Rejected' является самой поздней датой для данного id.

Более традиционные методы используют коррелированный подзапрос:

select t.*
from #temp t
where t.mydate = (select max(t2.mydate)
                  from #temp t2
                  where t2.id = t.id
                 ) and
      t.status = 'Rejected';

Или оконные функции:

select t.*
from (select t.*,
             row_number() over (partition by id order by mydate desc) as seqnum
      from #temp t
     ) t
where t.seqnum = 1 and t.status = 'Rejected';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...