2016-10-19 6 views
0

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

Фильтр: ОТ '2016-08-11 23: 50: 00.000' К '2016-08-13 01: 15: 00.000' - 85 минут, как выделен в желтый цвет

ценам ниже

Фильтры как показано ниже -

Когда я даю следующие фильтры, а затем

DECLARE @StartDate DATETIME = '2016-08-11 23:50:00.000' 
DECLARE @EndDate DATETIME = '2016-08-15 01:15:00.000' 

в идеале, он должен рассмотреть окно времени, как -

2016-08-11 23:50:00 to 2016-08-12 01:15:00 - 85 minutes 
2016-08-12 23:50:00 to 2016-08-13 01:15:00 - 85 minutes 
2016-08-13 23:50:00 to 2016-08-14 01:15:00 - 85 minutes 
2016-08-14 23:50:00 to 2016-08-15 01:15:00 - 85 minutes 
2016-08-15 23:50:00 to 2016-08-16 01:15:00 - 85 minutes 

и так далее ....

UPDATE 3

enter image description here

Может кто-то помочь мне с этим запросом?

Sample Data -

create table #temp1 ([State] varchar(20),StartTimeStamp Datetime2, EndTimeStamp Datetime2, DurationInSeconds int) 
Insert into #temp1 values('Away',  '2016-08-11 23:40:00.000000',   '2016-08-11 23:45:00.000000', 300 ) 
,('Appear Away','2016-08-11 23:45:00.000000',   '2016-08-11 23:50:00.000000', 300) 
,('Available', '2016-08-11 23:50:00.000000',   '2016-08-11 23:55:00.000000', 300) 
,('Available','2016-08-11 23:55:00.000000',    '2016-08-11 23:59:59.000000', 299) 
,('Away',  '2016-08-12 00:00:00.000000',   '2016-08-12 00:05:00.000000', 300) 
,('Offline', '2016-08-12 00:05:00.000000',   '2016-08-12 00:15:00.000000', 600) 
,('Away',  '2016-08-12 00:15:00.000000',   '2016-08-12 00:30:00.000000', 900) 
,('Appear Away','2016-08-12 00:30:00.000000',   '2016-08-12 01:15:00.000000', 2700) 
,('Away',  '2016-08-12 01:15:00.000000',   '2016-08-12 01:30:00.000000', 900) 
,('Offline', '2016-08-12 01:30:00.000000',   '2016-08-12 18:30:00.000000', 64800) 
,('Appear Away','2016-08-12 18:30:00.000000',   '2016-08-12 23:30:00.000000', 18000) 
,('Available', '2016-08-12 23:30:00.000000',   '2016-08-12 23:45:00.000000', 900) 
,('Away',  '2016-08-12 23:45:00.000000',   '2016-08-12 23:50:00.000000', 300) 
,('Offline', '2016-08-12 23:50:00.000000',   '2016-08-12 23:55:00.000000', 300) 
,('Available', '2016-08-12 23:55:00.000000',   '2016-08-12 23:59:59.000000', 299) 
,('Away',  '2016-08-13 00:00:00.000000',   '2016-08-13 00:05:00.000000', 300) 
,('Offline', '2016-08-13 00:05:00.000000',   '2016-08-13 00:15:00.000000', 600) 
,('Away',  '2016-08-13 00:15:00.000000',   '2016-08-13 00:30:00.000000', 900) 
,('Appear Away','2016-08-13 00:30:00.000000',   '2016-08-13 01:15:00.000000', 2700) 
,('Away',  '2016-08-13 01:15:00.000000',   '2016-08-13 01:30:00.000000', 900) 

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

enter image description here

+1

Пожалуйста, отредактируйте ваш вопрос и покажите результаты, которые вы хотите получить. Кроме того, вы можете объяснить красную линию. Что это значит? –

+0

Показать ожидаемый результат пожалуйста. – NEER

+0

Изменения, внесенные в вопрос @GordonLinoff –

ответ

2

Вы можете, как показано ниже:

DECLARE @StartDate DATETIME = '2016-08-8 17:00:00.000' 
DECLARE @EndDate DATETIME = '2016-08-15 18:00:00.000' 

;WITH TmpCte 
AS 
(
    SELECT 
     T.*, 
     IIF(T.StartTimeStamp < DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@StartDate AS TIME)), CAST(CAST(T.StartTimeStamp AS DATE) AS DATETIME)), 
       DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@StartDate AS TIME)), CAST(CAST(T.StartTimeStamp AS DATE) AS DATETIME)), 
       T.StartTimeStamp) AS TmpStart, 
     IIF(T.EndTimeStamp > DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@EndDate AS TIME)), CAST(CAST(T.EndTimeStamp AS DATE) AS DATETIME)), 
       DATEADD(ms, DATEDIFF(ms, '00:00:00', CAST(@EndDate AS TIME)), CAST(CAST(T.EndTimeStamp AS DATE) AS DATETIME)), 
       T.EndTimeStamp) AS TmpEnd   
    FROM 
     #temp T 
), CTE as (
    SELECT * FROM 
    (
      SELECT 
      *, 
      ABS(DATEDIFF(SECOND, TmpStart, TmpEnd)) TmpDuration 
      FROM TmpCte 
      where 
      TmpStart >= @StartDate and 
      TmpEnd <= @EndDate AND 
      TmpEnd > TmpStart  
    ) A 
    PIVOT(SUM(TmpDuration) 
    FOR state IN ([Appear Away],[Available],[Away],[Offline],[online]) ) as  Pivottable 

) 
    select CAST(StartTimestamp as Date) as LocalDate,SUM([Available]) as [Available] , SUM([Away]) as Away,SUM([Online]) as [Online], 
    SUM(Offline) as [Offline] 
    from CTE 
    group by CAST(StartTimestamp as Date) 

Результат:

+------------+-----------+------+--------+---------+ 
| LocalDate | Available | Away | Online | Offline | 
+------------+-----------+------+--------+---------+ 
| 2016-08-11 |  600 | 1039 | 163 |  600 | 
+------------+-----------+------+--------+---------+ 
+1

Спасибо большое @NEER. Идеальный ответ. :) –

0

Попробуйте нижеследующее.

DECLARE @StartDate DATETIME = '2016-08-11 23:45:00.000' 
DECLARE @EndDate DATETIME = '2016-08-12 01:00:00.000' 

;WITH TmpCte 
AS 
(
    SELECT 
     T.*, 
     IIF(T.StartTimeStamp < @StartDate, 
       @StartDate, 
       T.StartTimeStamp) AS TmpStart, 
     IIF(T.EndTimeStamp > @EndDate,    
       @EndDate, 
       T.EndTimeStamp) AS TmpEnd   
    FROM 
     #temp T 
), CTE as (
    SELECT * FROM 
    (
      SELECT 
      *, 
      ABS(DATEDIFF(SECOND, TmpStart, TmpEnd)) TmpDuration 
      FROM TmpCte 
      where 
      TmpStart >= @StartDate and 
      TmpEnd <= @EndDate AND 
      TmpEnd > TmpStart  
    ) A 
    PIVOT(SUM(TmpDuration) 
    FOR state IN ([Appear Away],[Available],[Away],[Offline],[online]) ) as  Pivottable 

) 
    SELECT 
    CAST(StartTimestamp as Date) as LocalDate, 
    SUM([Appear Away]) as [Appear Away], 
    SUM([Available]) as [Available] , 
    SUM([Away]) as Away,SUM([Online]) as [Online], 
    SUM(Offline) as [Offline] 
    from CTE 
    group by CAST(StartTimestamp as Date) 
+0

Это не сработает, если у меня есть несколько дней. Если у меня есть переход с 11:30 до 1:00 и в несколько дней, это не сработает. Тем не менее, в вашем первом ответе, смена была с 17:00 (17:00) до 18:00 (18:00) на каждый день, и она работала правильно. –

+0

Когда я дам следующие фильтры: DECLARE @ -StartDate DATETIME = '2016-08-11 23: 00: 00.000' DECLARE @ -EndDate DATETIME = '2016-08-15 01:00:00.000 ' Тогда в идеале следует учитывать временное окно как - 2016-08-11 23:00:00 - 2016-08-12 01:00:00 2016-08-12 23:00:00 до 2016-08-13 01:00:00 2016-08-13 23:00:00 - 2016-08-14 01:00:00 2016-08-14 23:00:00 до 2016-08-15 01 : 00: 00 2016-08-15 23:00:00 до 2016-08-16 01:00:00 –

+0

@RameshwarPawale Не ясно для меня. Этот запрос дает ожидаемый результат. В чем проблема? – NEER