Выбор временных интервалов значения live - пропущены первый и последний интервалы - PullRequest
2 голосов
/ 09 марта 2011

У меня есть таблица со следующей структурой

|ChangedDate |IDParameter |ChangedTo (битовый столбец) |

Поэтому мне нужно получить временные интервалы, когда мой параметр имеет значение True или False, например:

|IDParameter |ChangedToDate1 |ChangedToDate2 |ChangedTo (true to false || false to true)

, и я делаю

With RankedDates As
(
    Select T1.[ChangedDate], T1.ID, T1.[ChangedToValue]
    , Row_Number() Over( Partition By T1.ID Order By T1.[ChangedDate] ) As Num
    From [Changes] As T1
 )

  SELECT T1.[ID]
      ,T2.[ChangedToValue]
      ,T1.[ChangedDate] AS startDate
      ,T2.[ChangedDate] AS endDate
  FROM [RankedDates] AS T1
    Join RankedDates As T2
                    On T2.ID = T1.ID
                          And T2.Num = T1.Num + 1
                          And T2.[ChangedToValue] <> T1.[ChangedToValue]
                    Order By T2.[ChangedDate]

Проблема в том, что я пропускаю первый и последний интервалы здесь.это должно быть NULL для даты начала, если это первое, и NULL для endDate для последнего интервала для каждого ID параметра. Я думаю, мне нужно добавить его с помощью UNION, но я не могу понять, как добавить его для каждого IDParameter.

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

ms sql server 2008

извините за такой сложный вопрос.

Пример:

08.03.2011 ID1 0 -> 1 
09.03.2011 ID1 1 -> 0
09.03.2011 ID2 0 -> 1 
10.03.2011 ID1 0 -> 1 
10.03.2011 ID2 1 -> 0

-->

NULL , 08.03.2011 ID1 is 0
NULL , 09.03.2011 ID2 is 0
08.03.2011, 09.03.2011 ID1 is 1
09.03.2011, 10.03.2011 ID2 is 1
09.03.2011, 10.03.2011 ID1 is 0
10.03.2011, NULL ID1 is 1
10.03.2011, NULL ID2 is 0

Ответы [ 2 ]

2 голосов
/ 09 марта 2011

как насчет использования FULL JOIN вместо JOIN?

Решает ли это вашу проблему?

EDIT:

Я думаю, что это должно работать, как вы хотите.

select  isnull(T1.ID, T2.ID) as ID
        ,isnull(T2.[ChangedToValue], case when T1.[ChangedToValue] = 1 then 0 else 1 end) as [ChangedToValue]
        ,T1.[ChangedDate] as startdate
        ,T2.[ChangedDate] as enddate
from    [RankedDates] T1
full join [RankedDates] T2
    on T2.num = T1.num +1
    and T2.ID = T1.ID
    and T1.[ChangedToValue] <> T2.[ChangedToValue]

order by 
    case when T2.[ChangedDate] is null then 1 else 0 end
    ,T2.[ChangedDate]

Вы были правы относительно ChangedToValue, я изменил его, чтобы теперь показывать обратное, если T2 равен нулю.

1 голос
/ 09 марта 2011

Предполагается, что так выглядит ваша базовая таблица:
ChangeDate IDParameter ChangedTo
2011-03-08 ID1 True
2011-03-09 ID1 False
2011-03-09 ID2 True
2011-03-10 ID1 True
2011-03-10 ID2 False

SELECT  (SELECT TOP 1 t0.[ChangeDate] FROM [calendardb].[dbo].[Table_1] t0 
WHERE t0.IDParameter = t1.IDParameter AND t0.ChangeDate < t1.ChangeDate ORDER 
BY t0.ChangeDate DESC),
   [ChangeDate]
  ,[IDParameter]
  ,[ChangedTo]
FROM [calendardb].[dbo].[Table_1] t1
UNION 
SELECT MAX(ChangeDate) as maxd ,NULL,[IDParameter],
(SELECT ChangedTo FROM [calendardb].[dbo].[Table_1] t0 WHERE t0.ChangeDate =    (SELECT MAX(ChangeDate) FROM [calendardb].[dbo].[Table_1]
GROUP BY [IDParameter] HAVING IDParameter = t1.IDParameter) AND t1.IDParameter = t0.IDParameter)

FROM [calendardb].[dbo].[Table_1] t1
GROUP BY [IDParameter]

даст вам такой результат:

NULL 2011-03-08 ID1 1
2011-03-08 2011-03-09 ID1 0
NULL 2011-03-09 ID2 1
2011-03-09 2011-03-10 ID1 1
2011-03-09 2011-03-10 ID2 0
2011-03-10 NULL ID1 1
2011-03-10 NULL ID2 0

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