Рассчитать разницу между датами в разных строках набора данных - PullRequest
0 голосов
/ 21 мая 2019

Стол выглядит так:

CREATE TABLE [dbo].[HistDT](
    [ID] [bigint] NULL,
    [StartDtSK] [varchar](8) NULL,
    [StartDt] [datetime] NULL,
    [status] [nvarchar](30) NULL,
) ON [PRIMARY]

Пример набора данных:

ID | StartDtSK | StartDt              | Status |
1     20190520   20-05-2019 12:00:13      10
1     20190520   20-05-2019 10:00:00       5
1     20190414   14-04-2019 13:23:00       2
2     20190312   12-03-2019 10:03:00      10
2     20190308   08-03-2019 18:03:00       1
etc..   

Мне нужен запрос, который будет отображать количество дней, проведенных в каждом статусе. Это было бы легко, если бы у таблицы, которую я унаследовал, была дата окончания. Затем я вычислю значения datediff и пивот для значений столбца status.

Может быть, мне следует создать новую таблицу, используя ssis, где я добавлю столбец EndDt, который будет StartDt последнего добавленного статуса. Но есть ли способ сделать это без создания другой таблицы?

Ответы [ 2 ]

1 голос
/ 21 мая 2019

SQL Server 2008

Это не очень красиво, и я не проверял его для всех случаев использования.Я надеюсь, что вы можете использовать его или найти вдохновение.Я уверен, что есть лучший способ:)

declare @table2 table (
    [ID] [bigint] NULL,
    [StartDtSK] [varchar](8) NULL,
    [StartDt] [datetime] NULL,
    [status] [nvarchar](30) NULL
) 

insert into @table2

values
(1 ,   '20190520','2019-05-20 12:00:13','10'),


(1 ,   '20190520','2019-05-20 10:00:00','5'),

(1 ,   '20190414','2019-04-14 13:23:00','2'),
(2,     '20190312',   '2019-03-12 10:03:00',      '10'),
(2 ,    '20190308',   '2019-03-08 18:03:00',       '1')

select *,DATEDIFF(dd,startdt,enddate) as TotalDAys from (
select x.ID,StartDtSK,Startdt,[Status],Enddate from (
select *,ROW_NUMBER() over(partition by id order by startdt) as rn from @table2
) x
cross apply ( select * from (select id,StartDt as Enddate,ROW_NUMBER() over(partition by id order by startdt) as rn2  from @table2 b
)f where (rn +1 = f.rn2 ) and x.id = f.id ) d

union all
select ID,StartDtSK,startdt,[Status],'9999-12-31' as Enddate from (
select *,ROW_NUMBER() over(partition by id order by startdt desc) as rn from @table2
)X where rn=1
)y 
order by id,startdt

SQL Server 2008 без перекрестного применения

Это может быть немного большеpretty:)

select *,DATEDIFF(dd,startdt,enddate) as TotalDAys from (
select x.ID,StartDtSK,Startdt,[Status],case when Enddate is null then '9999-12-31' else Enddate end as Enddate from (
select *,ROW_NUMBER() over(partition by id order by startdt) as rn from @table2
) x
left join ( 
select * from (select id,StartDt as Enddate,ROW_NUMBER() over(partition by id order by startdt) as rn2  from @table2 b
)f  ) d on  (rn +1 = d.rn2 ) and x.id = d.id

)y 

SQL Server 2012 и выше:

Это то, что вы хотите?

declare @table2 table (
    [ID] [bigint] NULL,
    [StartDtSK] [varchar](8) NULL,
    [StartDt] [datetime] NULL,
    [status] [nvarchar](30) NULL
) 

insert into @table2

values
(1 ,   '20190520','2019-05-20 12:00:13','10'),


(1 ,   '20190520','2019-05-20 10:00:00','5'),

(1 ,   '20190414','2019-04-14 13:23:00','2')

select *,Datediff(dd,Startdt,Enddate) as TotalDays from (
select *,LAG(StartDt,1,'9999-12-31') over(partition by ID order by StartDT desc) as EndDate from @table2
)x

Вставьтеправило, которое обрабатывает текущее состояние (9999-12-31) дата

enter image description here

0 голосов
/ 21 мая 2019

Возможно, функция LEAD полезна для вашего вопроса.

Как это

IsNull(DateAdd(SECOND,-1,Cast(LEAD ([StartDt],1) OVER (PARTITION BY [status] ORDER BY [StartDt]) AS DATETIME)),getdate()) AS EndDate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...