Выберите, какая из них имеет последнюю дату для каждого элемента

#sql #sql-server

Вопрос:

У меня есть 2 таблицы, скажем, TableA и TableB.

Таблица А

 create table tableA
(ID int, DocumentDate datetime2, DocumentName varchar(3), ItemID int);

insert into tableA (ID, DocumentDate, DocumentName, ItemID)
values (1, '2019-08-01 12:00:00', 'A-1', 1),
(2, '2020-05-12 13:00:00', 'B-2', 1),
(3, '2021-07-01 14:00:00', 'C-3', 1),
(4, '2020-01-01 12:00:00', 'D-4', 2),
(5, '2021-02-01 13:00:00', 'E-5', 2),
(6, '2021-07-02 14:00:00', 'F-6', 2);
 

а это таблица В

 create table tableB
(ID int, ItemCode varchar(3));

insert into tableB (ID, ItemCode)
values (1, 'AAA'),
(2, 'BBB');
 

вот мой запрос SQL Server

 select 
    A.ID, 
    A.DocumentDate, 
    A.DocumentName, 
    B.ItemCode 
from tableA A
left join tableB B on B.ID = A.ItemID
 

и результат должен быть таким

Я хочу выбрать 3-й для AAA и 6-й для BBB, у которого самая последняя дата. Спасибо.

Комментарии:

1. «и результат должен быть таким «? Это результат, который вы получаете с помощью своего запроса (все шесть строк). Разве тебе не нужны только двое из них? Ваш следующий абзац, кажется, говорит об этом. И, пожалуйста, не используйте изображения. Вставьте таблицу в текстовом формате в свой запрос.

Ответ №1:

Вы можете использовать apply :

 select b.*, a.*
from tableB b outer apply
     (select top (1) a.*
      from tableA a
      where a.itemId = b.Id
      order by a.documentdate desc
     ) a;
 

С включенным индексом tableA(item, documentdate) это часто будет иметь очень хорошую производительность

Ответ №2:

Кажется, все достаточно просто:

 WITH cteDocuments As
(
    SELECT
        ID,
        DocumentDate,
        DocumentName,
        ItemID,
        ROW_NUMBER() OVER (PARTITION BY ItemID ORDER BY DocumentDate DESC) As RN
    FROM
        tableA
)
SELECT
    A.ID,
    A.DocumentDate,
    A.DocumentName,
    B.ItemCode
FROM
    cteDocuments As A
    LEFT JOIN tableB As B ON B.ID = A.ItemID
WHERE
    A.RN = 1
;
 

НОМЕР СТРОКИ