Создание нового поля даты динамически из следующей строки - PullRequest
0 голосов
/ 29 июля 2010

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

Ответы [ 6 ]

2 голосов
/ 29 июля 2010

Я предполагаю, что в настоящее время у вас есть строки со значениями, такими как

StartDate
---------
1 Jan 1990
2 June 1998
4 September 2006

И вы хотите изменить на

StartDate              EndDate
---------              ------------
1 Jan 1990             2 June 1998
2 June 1998            4 September 2006
4 September 2006       NULL

Совершенно независимо от проблемы избыточности и обслуживания, которая напоминает мне о этом вопросе , где такая установка с коррелированными столбцами фактически вызывала проблемы с исходным плакатом при запросе данных. (Я предпочитаю Необоснованный ответ своему на этот вопрос!)

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

Редактировать После долгих разговоров с row_number() Я не смог найти запрос с лучшим планом, чем этот. (Предполагается индекс на StartDate)

SELECT 
        id,
        StartDate, 
           (SELECT MIN(StartDate) 
            FROM  testTable t2 
            WHERE t2.StartDate > t1.StartDate) AS EndDate
FROM testTable t1
2 голосов
/ 29 июля 2010

Прежде всего, вам нужно придумать определение «порядка», так как строки в таблице хранятся без какого-либо порядка.

Когда вы знаете, каков ваш заказ, вы можете создать хранимую процедуру, которая будет:

insert into the_table (new_id, start_date) values (@id, @start_date);

update the_table
set end_date = @start_date
where id = <the id determined by your sorting rule>;
1 голос
/ 29 июля 2010

Если у вас уже есть столбцы и у вас есть первичный ключ с автоинкрементом:

Update T1
Set T1.EndDate = T2.StartDate
From [Table] T1
Inner Join [Table] T2 on T1.Id = T2.Id - 1
1 голос
/ 29 июля 2010

Зависит от того, что вы подразумеваете под "следующей" строкой.

Можете ли вы предоставить пример набора данных и указать, как вы определяете, в каком порядке располагаются строки?

EDIT

Ваш порядок записи действительно имеет значение - вам придется определить, что это такое. Сейчас я работаю над предположением, что упорядочение по start_date приемлемо.

--GET the first relevant start date
declare @start datetime
set @start = select MIN(start_date) from table

declare @end datetime
set @end = @start

WHILE @end is not null

  --GET the next relevant end date
  SET @end = select MIN(start_date) from table where start_date > @start

  --Update the table with the end date
  UPDATE table
  SET end_date = @end
  WHERE start_date = @start

  --GET the next relevant start date
  SET @start = @end

END
0 голосов
/ 03 ноября 2015

Я отвечаю на этот вопрос, потому что на него ссылаются где-то еще.

В зависимости от id отсутствие отверстий опасно. В столбцах identity могут быть пробелы, которые не принимаются во внимание в настоящее время принятым ответом.

В SQL Server 2012+ ответом будет просто lag(). В более ранних версиях вы можете использовать cross apply:

Update T1
    Set T1.EndDate = T2.StartDate
    From [Table] T1 cross apply
         (select top 1 t2.*
          from [Table] T2 
          where t2.StartDate > t1.Startdate
          order by t2.StartDate asc
         ) t2;

С индексом table(StartDate) это может даже иметь разумную производительность.

0 голосов
/ 29 июля 2010

А как насчет последнего ряда? EndDate будет пустым для этого?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...