2015-06-27 82 views
0

我想在連續日期的某個範圍內用數據寫一個sql查詢組。我用T-SQL。sql查詢組按連續日期某一範圍的數據

表:

Date  | MeterNo| Data | 
---------|---------|---------| 
01-06-15 | 12345 |  10 | 
02-06-15 | 12345 |  12 | 
03-06-15 | 12345 |  51 | 
04-06-15 | 12345 |  56 | 
05-06-15 | 12345 |  16 | 
06-06-15 | 12345 |  15 | 
07-06-15 | 12345 |  9 | 
08-06-15 | 12345 |  53 | 
09-06-15 | 12345 |  55 | 
10-06-15 | 12345 |  62 | 
11-06-15 | 12345 |  8 | 
12-06-15 | 12345 |  18 | 

我想通過結果有基團,例如如下:

|MeterNo| GroupName| StartDate | EndDate | 
|-------|----------|-----------|--------- | 
| 12345 | 0(<50) | 01-06-15 | 02-06-15| 
| 12345 | 1(>=50) | 03-06-15 | 04-06-15| 
| 12345 | 0(<50) | 05-06-15 | 07-06-15| 
| 12345 | 1(>=50) | 08-06-15 | 10-06-15| 
| 12345 | 0(<50) | 11-06-15 | 12-06-15| 

我需要的數據組是在連續時間小於50並大於50作爲下面。 我如何獲得SQL查詢來獲得第二個結果表的結果?提前致謝!

+0

請發表您嘗試 –

回答

3

這基本上是間隙和孤島的問題,您可以通過使用行號和檢查距離固定日期(例如日期0(= 1.1.1900))的每個日期的距離來將日期範圍組合在一起。所以,你可以通過這個得到結果:

select 
    MeterNo, 
    Grp, 
    min(Date) as StartDate, 
    max(Date) as EndDate 
from (
    select 
    MeterNo, 
    Date, 
    Grp, 
    datediff(day, 0, Date) - RN as DateGroup 
    from (
    select 
     Date, 
     MeterNo, 
     case when Data >= 50 then 1 else 0 end as Grp, 
     row_number() over (partition by MeterNo, 
      case when Data >= 50 then 1 else 0 end order by date asc) as RN 
    from 
     table1 
    ) X 
) Y 
group by 
    MeterNo, 
    Grp, 
    DateGroup 
Order by 
    MeterNo, 
    StartDate 

可以在SQL Fiddle

+0

許多thanks.off當然,你的解決方案作品完全。但它允許選擇一個答案。 – stkflmb12

1

測試這方面的一些替代解決方案:

declare @t table([Date] date, [MeterNo] int, [Data] int); 

INSERT INTO @t VALUES 
    ('2015-06-01', 12345, 10), 
    ('2015-06-02', 12345, 12), 
    ('2015-06-03', 12345, 51), 
    ('2015-06-04', 12345, 56), 
    ('2015-06-05', 12345, 16), 
    ('2015-06-06', 12345, 15), 
    ('2015-06-07', 12345, 9), 
    ('2015-06-08', 12345, 53), 
    ('2015-06-09', 12345, 55), 
    ('2015-06-10', 12345, 62), 
    ('2015-06-11', 12345, 8), 
    ('2015-06-12', 12345, 18); 

with cte as(select *, 
        case when data < 50 then 0 else 1 end gr1, 
        ROW_NUMBER() over(partition by MeterNo order by date)- 
        ROW_NUMBER() over(partition by MeterNo, 
                case when data < 50 then 0 else 1 end 
            order by date) gr2 
      from @t) 
select MeterNo, 
     MIN(date) StartDate, 
     MAX(date) EndDate, 
     case when gr1 = 0 then '0(<50)' else '1(>=50)' end as GroupName 
from cte 
group by MeterNo, gr1, gr2 
order by StartDate 
+0

謝謝!有用。 – stkflmb12

+0

@ stkflmb12這種方法有一個可能的缺陷。如果日期可能完全從表格中遺漏,則完全沒有注意到。 –

+0

@JamesZ你能舉出一個可能的缺陷的例子嗎? – stkflmb12