В наборе дат и чисел выберите последнюю следующую ближайшую дату до даты, когда число равно

#sql #sql-server #tsql

Вопрос:

В приведенной ниже таблице для каждой учетной записи есть ли способ перенести последнюю ближайшую ближайшую дату на дату, когда Запасы = 5?

Учетная запись Дата Инвентарь
123 2019-04-01 5
123 2019-05-01 6
123 2019-07-01 9
123 2019-08-01 5
123 2019-09-01 8
123 2019-10-01 9
54321 2018-01-01 5
54321 2018-02-01 7
54321 2018-03-01 5
54321 2018-04-01 9
54321 2018-05-01 8

Ожидаемые результаты

Учетная запись Дата
123 2019-09-01
54321 2018-04-01

Ответ №1:

Вам нужно добавить столбец идентификаторов, или вы также можете сделать то же самое с помощью ROW_NUMBER (). Используйте запрос ниже:

 DECLARE @T TABLE (
    ID INT IDENTITY
    ,Account INT
    ,[Date] DATE
    ,Inventory INT
    )

INSERT INTO @T
VALUES (123,'2019-04-01',5)
    ,(123,'2019-05-01',6)
    ,(123,'2019-07-01',9)
    ,(123,'2019-08-01',5)
    ,(123,'2019-09-01',8)
    ,(123,'2019-10-01',9)
    ,(54321,'2018-01-01',5)
    ,(54321,'2018-02-01',7)
    ,(54321,'2018-03-01',5)
    ,(54321,'2018-04-01',9)
    ,(54321,'2018-05-01',8)

SELECT Account
    ,[Date]
FROM @T
WHERE ID IN (
        SELECT MAX(ID)   1
        FROM @T
        WHERE Inventory = 5
        GROUP BY Account
        )
 

Выход:
введите описание изображения здесь

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

1. @Макс . . . Весьма удивительно, что вы приняли этот ответ. Во-первых, он использует столбец, которого нет в вашем вопросе. Что еще более важно, он используется identity для присвоения значения, а затем предполагает, что «далее» означает id 1 . Это просто неправильно по нескольким причинам, в том числе без гарантии того, что в идентификаторах нет пробелов, и без гарантии того, что следующий идентификатор будет даже для той же учетной записи. То, что происходит при работе с образцами данных, не означает, что запрос является правильным решением.

2. Спасибо, Гордон, ты прав, твое решение имеет больше смысла

Ответ №2:

Если вам нужна следующая строка в таблице , где id = 5 , то я бы ожидал lead() , что она будет использована:

 select account, max(next_date)
from (select t.*,
             lead(date) over (partition by account order by date) as next_date
      from t
     ) t
where inventory = 5
group by account;
 

Вот скрипка db<>.

Ответ №3:

 SELECT TOP 2 account
FROM table
WHERE inventory = 5
ORDER BY date DESC
 

Учебник по Sql Server