2017-01-17 5 views
2

私は遅延和、このような何かの毎日の歴史を持ついくつかのテーブル持っているのSQL Server 2012を使用します。同じIDの異なる時間に各セクションの最小日付を取得するにはどうすればいいですか? - SQL Serverの

SET DATEFORMAT YMD 
GO 
    CREATE TABLE [dbo].[testsum](
     [CID] [int], 
     [HDATE] [date], 
     [DELAYSUM] [numeric](16, 2) 
) 
GO 
INSERT [dbo].[testsum] ([CID], [HDATE], [DELAYSUM]) VALUES 
     (223,'2016-10-16',15503.80) 
     ,(223,'2016-10-17',15493.82) 
     ,(223,'2016-10-18',15489.25) 
     ,(223,'2016-10-19',15417.08) 
     ,(427,'2016-10-01',10375.89) 
     ,(427,'2016-10-02',10375.89) 
     ,(427,'2016-10-03',10385.91) 
     ,(427,'2016-10-16',8448.57) 
     ,(427,'2016-10-17',8443.13) 
     ,(427,'2016-10-18',8440.64) 
     ,(427,'2016-10-19',8401.31) 
     ,(427,'2016-10-20',8411.20) 
     ,(427,'2016-10-21',8414.58) 
     ,(427,'2016-10-22',8414.58) 
     ,(427,'2016-10-23',8414.58) 
     ,(427,'2016-10-24',8401.23) 
     ,(427,'2016-10-25',8393.92) 
     ,(427,'2016-10-26',8379.14) 
     ,(427,'2016-10-27',8374.57) 
     ,(427,'2016-10-28',8358.67) 
     ,(427,'2016-10-29',8358.67) 
     ,(427,'2016-10-30',8358.67) 
     ,(427,'2016-10-31',8346.61) 
     ,(541,'2016-10-05',900.44) 
     ,(541,'2016-10-06',832.84) 
     ,(541,'2016-10-11',637.54) 
     ,(541,'2016-10-15',413.89) 
     ,(541,'2016-10-16',413.89) 
     ,(541,'2016-10-17',413.89) 
     ,(541,'2016-10-18',1728.12) 
     ,(541,'2016-10-22',265.27) 
     ,(541,'2016-10-23',265.27) 
     ,(541,'2016-10-24',265.27) 
     ,(541,'2016-10-25',787.10) 
     ,(541,'2016-10-26',1222.29) 

月に3つのIDのデータ例:

CID   HDATE  DELAYSUM 
    ----------- ---------- --------------------------------------- 
    223  2016-10-16 15503.80 
    223  2016-10-17 15493.82 
    223  2016-10-18 15489.25 
    223  2016-10-19 15417.08 
    427  2016-10-01 10375.89 
    427  2016-10-02 10375.89 
    427  2016-10-03 10385.91 
    427  2016-10-16 8448.57 
    427  2016-10-17 8443.13 
    427  2016-10-18 8440.64 
    427  2016-10-19 8401.31 
    427  2016-10-20 8411.20 
    427  2016-10-21 8414.58 
    427  2016-10-22 8414.58 
    427  2016-10-23 8414.58 
    427  2016-10-24 8401.23 
    427  2016-10-25 8393.92 
    427  2016-10-26 8379.14 
    427  2016-10-27 8374.57 
    427  2016-10-28 8358.67 
    427  2016-10-29 8358.67 
    427  2016-10-30 8358.67 
    427  2016-10-31 8346.61 
    541  2016-10-05 900.44 
    541  2016-10-06 832.84 
    541  2016-10-11 637.54 
    541  2016-10-15 413.89 
    541  2016-10-16 413.89 
    541  2016-10-17 413.89 
    541  2016-10-18 1728.12 
    541  2016-10-22 265.27 
    541  2016-10-23 265.27 
    541  2016-10-24 265.27 
    541  2016-10-25 787.10 
    541  2016-10-26 1222.29 

は出力が必要に(各期間(区間)の終了日とのIDS(CID)の日付の各セクションの最小日付) セグメントは、1日以上によって分離されている:

CID   HDATE  DELAYSUM END_DATE 
    ----------- ---------- --------------------------------------- 
    223  2016-10-16 15503.80 2016-10-19 
    427  2016-10-01 10375.89 2016-10-03 
    427  2016-10-16 8448.57  2016-10-31 
    541  2016-10-05 900.44  2016-10-06 
    541  2016-10-11 637.54  2016-10-11 
    541  2016-10-15 413.89  2016-10-18 
    541  2016-10-22 265.27  2016-10-26 

今のところこの作業に悩まされています。 私の英語は申し訳ありません。これを解決するための

答えて

1

ここで重要なのは、連続する行の間の日付の差は1。このクエリはそれを行うには、論理dateadd(day,-row_number() over (partition by cid order by hdate),hdate)を使用している場合は、同じグループにCIDごとのレコードを分類することです。内部クエリを実行して、グループの割り当て方法を確認します。

その後、ウィンドウ関数min,maxおよびfirst_valueを使用すると、前に割り当てられたグループを使用して、cidあたりの最小遅延、最大遅延および最初の遅延値を取得できます。

SELECT DISTINCT cid, 
       min(hdate) over (partition BY cid, grp) AS hdate, 
       first_value(delaysum) over (partition BY cid, grp ORDER BY hdate) AS delaysum, 
       max(hdate) over (partition BY cid, grp) AS end_date 
FROM (SELECT t.* , 
     dateadd(DAY,-row_number() over (partition BY cid ORDER BY hdate),hdate) AS grp 
     FROM testsum t) x 
ORDER BY cid,hdate 

Sample Demo

+0

uがクールです! Thk u! –

0

一つの方法は、行番号の違いです:

select cid, min(hdate), max(hdate), min(delaysum) 
from (select t.*, 
      row_number() over (order by hdate) as seqnum, 
      row_number() over (partition by cid order by hdate) as seqnum_c 
     from testsum t 
    ) t 
group by cid, (seqnum - seqnum_c); 

編集:私はよく見るとあなたではなく、最小値よりも、最初の値が欲しいよう

、それが見えます。 SQL Serverは集計関数としてfirst_value()(まだ)を提供していません。だから、:

select cid, min(hdate), max(hdate), min(first_delaysum) 
from (select t.*, 
      first_value(delaysum) over (partition by cid, seqnum - seqnum_c order by hdate) as first_delaysum 
     from (select t.*, 
        row_number() over (order by hdate) as seqnum, 
        row_number() over (partition by cid order by hdate) as seqnum_c 
      from testsum t 
      ) t 
    ) t 
group by cid, (seqnum - seqnum_c);     
関連する問題