Работа с датами из нескольких строк

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

Например, для идентификатора 513 первой строкой будет 2008-01-01 и 2010-04-16, а второй строкой будет 2010-04-17, 2011-04-25.

Я не уверен, как я мог бы добиться этого без курсора.

Create Table #Temp
(
    ID int,
    Amount money,
    StartDate datetime
)

insert into #Temp
(
    ID,
    Amount,
    StartDate
)
select 513,240.00,'2008-01-01 00:00:00' union all
select 513,240.00,'2010-04-17 00:00:00' union all
select 513,265.00,'2011-04-26 00:00:00' union all
select 513,275.00,'2012-04-17 00:00:00' union all
select 513,285.00,'2013-04-22 00:00:00' union all
select 513,325.00,'2015-06-15 00:00:00' union all
select 513,335.00,'2017-06-15 00:00:00' union all
select 514,280.00,'2001-01-22 00:00:00' union all
select 514,280.00,'2010-06-09 00:00:00' union all
select 515,240.00,'2019-01-01 00:00:00' union all
select 515,240.00,'2010-04-17 00:00:00' union all
select 515,265.00,'2011-04-26 00:00:00' union all
select 515,275.00,'2012-04-17 00:00:00' union all
select 515,285.00,'2013-04-22 00:00:00' union all
select 515,325.00,'2015-06-15 00:00:00' union all
select 515,335.00,'2017-06-15 00:00:00'

select * from #Temp

drop table #Temp
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
44
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете использовать LEAD() и DATEADD() для достижения результата:

SELECT *, DATEADD(DAY, -1, LEAD (StartDate, 1) OVER (PARTITION BY ID ORDER BY StartDate)) AS ENDDATE
FROM #Temp

Демонстрация на db<>скрипке

Вы можете использовать свинец, и он работает так, как вы ожидаете в требовании,

select *, lead(StartDate-1) over(partition by id order by id,startdate) as EndDate 
from #Temp

ДЛЯ SQL Server 2005+:

   WITH CTE AS(
        SELECT ROW_NUMBER() OVER(PARTITION BY ID ORDER BY StartDate) as row_num,
        ID, Amount, StartDate FROM #Temp 
    )
    SELECT
    prev.ID,
    prev.Amount,
    prev.StartDate,
    DATEADD(DAY, -1, ISNULL(prev.StartDate,1)) AS EndDate
    FROM CTE prev
    LEFT JOIN CTE nex ON nex.rownum = CTE.rownum + 1
select t1.* ,  dateadd(day,-1,t2.dt) enddate
from  (select row_number()over(partition by ID order by ID) srno,  ID,  StartDate dt from #Temp) t1 
left join (select row_number()over(partition by ID order by ID) srno,   ID,  StartDate dt from #Temp)t2 on  t1.srno =(t2.srno-1)and  t1.ID = t2.ID

Другие вопросы по теме