2016-04-20 1 views
1

У меня есть база данных для всех температур за последние 10 лет. Теперь я хочу найти все периоды, когда температура была выше. 15 градусов.SQL Время запроса от определенного значения

Simplified example: 
... 
2015-05-10 12 
2015-05-11 15 | 
2015-05-12 16 | 
2015-05-13 17 | 
2015-05-14 16 | 
2015-05-15 15 | 
2015-05-16 12 
2015-05-17 11 
2015-05-18 15 | 
2015-05-19 12 
2015-05-20 18 | 
... 

Så теперь я хочу получить все периоды времени, как это:

Min   Max 
2015-05-11 2015-05-15 
2015-05-18 2015-05-18 
2015-05-20 2015-05-20 

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

+1

выглядит как вариант зазорами и островов проблемы. вы хотите найти острова строк, которые имеют значение выше 15 и обрабатывают другие строки, такие как пробелы. –

ответ

1

Вы можете использовать CTE

CREATE TABLE #Date (DateT datetime, Value int) 

INSERT INTO #Date 
VALUES ('2015-05-10',12), 
     ('2015-05-11',15), 
     ('2015-05-12',16), 
     ('2015-05-13',17), 
     ('2015-05-14',16), 
     ('2015-05-15',15), 
     ('2015-05-16',12), 
     ('2015-05-17',11), 
     ('2015-05-18',15), 
     ('2015-05-19',12), 
     ('2015-05-20',18) 



WITH t AS (
      SELECT DateT d,ROW_NUMBER() OVER(ORDER BY DateT) i 
      FROM #Date 
      WHERE Value >= 15 
      GROUP BY DateT 
     ) 


SELECT MIN(d) as DataStart,MAX(d) as DataFinal, ROW_NUMBER() OVER(ORDER BY DATEDIFF(day,i,d)) as RN 
FROM t 
GROUP BY DATEDIFF(day,i,d) 

RN столбец не является обязательным, вы можете использовать

SELECT MIN(d) as DataStart,MAX(d) as DataFinal 
FROM t 
GROUP BY DATEDIFF(day,i,d) 
0

Вот решение с использованием алгоритма пробелов и островов. Он выглядит довольно громоздким, но он работает быстро и отлично масштабируется. Он также является модульным, если вы хотите добавить параметр разрешенного пробела, и вы можете переписать его на раздел другими столбцами, и он все равно будет работать хорошо.

Вдохновленный Питер Larssons пост здесь: http://www.sqltopia.com/?page_id=83

WITH [theSource](Col1,Col2) 
AS 
(
SELECT Col1,Col2 FROM (VALUES 
('2015-05-10',12), 
('2015-05-11',15), 
('2015-05-12',16), 
('2015-05-13',17), 
('2015-05-14',16), 
('2015-05-15',15), 
('2015-05-16',12), 
('2015-05-17',11), 
('2015-05-18',15), 
('2015-05-19',12), 
('2015-05-20',18) 
) as x(Col1,Col2) 
) 
,filteredSource([Value]) 
AS 
(
SELECT Col1 as [Value] 
FROM theSource WHERE Col2 >= 15 
) 
,cteSource(RangeStart, RangeEnd) 
AS (
    SELECT RangeStart, 
     CASE WHEN [RangeStart] = [RangeEnd] THEN [RangeEnd] ELSE LEAD([RangeEnd]) OVER (ORDER BY Value) END AS [RangeEnd] 
     FROM (
      SELECT [Value], 
       CASE 
        WHEN DATEADD(DAY,1,LAG([Value]) OVER (ORDER BY [Value])) >= [Value] THEN NULL 
        ELSE [Value] 
       END AS RangeStart, 
       CASE 
        WHEN DATEADD(DAY,-1,LEAD([Value]) OVER (ORDER BY [Value])) <= [Value] THEN NULL 
        ELSE [Value] 
           END AS RangeEnd 
         FROM filteredSource 
       ) AS d 
    WHERE RangeStart IS NOT NULL 
     OR RangeEnd IS NOT NULL 
) 


SELECT RangeStart AS [Min], 
    RangeEnd AS [Max] 
FROM cteSource 
WHERE RangeStart IS NOT NULL; 
+0

Что делать, если у вас есть разрыв в днях? Скажите, если вам не хватает данных за несколько дней в течение 10 лет – Geir

+0

Thats ok. Это показывает только острова. –

Смежные вопросы