Прерывистые временные ряды.Возврат первой даты последнего непрерывного блока самых последних данных в T-SQL - PullRequest
3 голосов
/ 17 марта 2011
10/03/2011 11/03/2011 12/03/2011 13/03/2011 14/03/2011  15/03/2011  QUERYRESULT
a             a          a                      a            a       14/03/2011
                                    b           b            b       13/03/2011
c                        c          c           c                    12/03/2011





Таким образом, для самого последнего блока смежных дат, вернуть самую раннюю дату из этого конкретного блока, как показано в столбце «queryresult».

Теперь я понимаю, что я случайно перенесДанные в приведенном мною примере Для источника можно предположить, что схема имеет вид: [ID] 1,2,3, ...;[тип] a, b, c ..;[дата]

Я могу что-то увидеть с помощью рекурсивных функций CTE / окна / ранжирования, но не могу понять это.

Ответы [ 2 ]

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

проще, чем я думал, и не нуждается в CTE или функциях управления окнами / ранжирования:

при условии, что данные

ID  mydate  pfo
1   12/03/2011  a
4   13/03/2011  a
6   14/03/2011  a
10  16/03/2011  a
2   12/03/2011  b
5   13/03/2011  b
8   15/03/2011  b
3   12/03/2011  c
7   14/03/2011  c
9   15/03/2011  c
11  16/03/2011  c

тогда

SELECT 

    MAX( n.mydate)
   ,n.pfo

 FROM testtable n

 LEFT OUTER JOIN
 testtable n2 ON  n.pfo                  = n2.pfo 
              AND DATEADD(D,-1,n.mydate) = n2.mydate

 WHERE n2.mydate IS NULL

 GROUP BY n.pfo

1 голос
/ 17 марта 2011
;WITH data (type, date) AS (
  SELECT 'a', CAST('20110310' AS datetime) UNION ALL
  SELECT 'a', CAST('20110311' AS datetime) UNION ALL
  SELECT 'a', CAST('20110312' AS datetime) UNION ALL
  SELECT 'a', CAST('20110314' AS datetime) UNION ALL
  SELECT 'a', CAST('20110315' AS datetime) UNION ALL
  SELECT 'b', CAST('20110313' AS datetime) UNION ALL
  SELECT 'b', CAST('20110314' AS datetime) UNION ALL
  SELECT 'b', CAST('20110315' AS datetime) UNION ALL
  SELECT 'c', CAST('20110310' AS datetime) UNION ALL
  SELECT 'c', CAST('20110312' AS datetime) UNION ALL
  SELECT 'c', CAST('20110313' AS datetime) UNION ALL
  SELECT 'c', CAST('20110314' AS datetime)
),
grouped AS (
  SELECT
    type,
    date,
    groupID = DATEADD(day, -ROW_NUMBER() OVER (PARTITION BY type ORDER BY date), date)
  FROM data
),
startdates AS (
  SELECT
    type,
    groupStartDate = MIN(date)
  FROM grouped
  GROUP BY type, groupID
)
SELECT
  type,
  LastGroupStartDate = MAX(groupStartDate)
FROM startdates
GROUP BY type
...