2016-06-29 9 views
0

テーブルの行を個別の時間枠でグループ化したいと思います。個別の時間枠でグループ化する

例として、我々は空港で出発のリストを持っている想像してみましょう:次のクエリを使用して、完全な時間(日、週、...)によって

| Departure   | Flight | Destination | 
| 2016-06-01 10:12:00 | LH1234 | New York | 
| 2016-06-02 14:23:00 | LH1235 | Berlin  | 
| 2016-06-02 14:30:00 | LH1236 | Tokio  | 
| 2016-06-03 18:45:00 | LH1237 | Belgrad  | 
| 2016-06-04 04:10:00 | LH1237 | Rio   | 
| 2016-06-04 06:20:00 | LH1237 | Paris  | 

私がすることができます簡単にグループのデータを:

select to_char(departure, 'HH24') as "full hour", count(*) as "number flights" 
from departures 
group by to_char(departure, 'HH24') 

この結果、次の表に示すようになります。今

| full hour | number flights | 
| 04  | 1    | 
| 06  | 1    | 
| 10  | 1    | 
| 14  | 2    | 
| 18  | 1    | 

私の質問:個々の時間枠でグループのデータにエレガントな方法(または ベストプラクティス)があります。 私が探している結果は以下の通りです:

| time frame       | number flights | 
| 2016-05-31 22:00 - 2016-06-01 06:00 | 0    | 
| 2016-06-01 06:00 - 2016-06-01 14:00 | 1    | 
| 2016-06-01 14:00 - 2016-06-01 22:00 | 0    | 
| 2016-06-01 22:00 - 2016-06-02 06:00 | 0    | 
| 2016-06-02 06:00 - 2016-06-02 14:00 | 0    | 
| 2016-06-02 14:00 - 2016-06-02 22:00 | 2    | 
| 2016-06-02 22:00 - 2016-06-03 06:00 | 0    | 
| 2016-06-03 06:00 - 2016-06-03 14:00 | 0    | 
| 2016-06-03 14:00 - 2016-06-03 22:00 | 1    | 
| 2016-06-03 22:00 - 2016-06-04 06:00 | 1    | 
| 2016-06-04 06:00 - 2016-06-04 14:00 | 1    | 
| 2016-06-04 14:00 - 2016-06-04 22:00 | 0    | 
| 2016-06-04 22:00 - 2016-06-05 06:00 | 0    | 

(。。0便での行は関係ありません彼らは問題のより良い視覚化のためだけに存在している)のための

おかげで、あなたの事前に回答してください。 :-) Peter

+0

時間ものを行うために派生テーブルにcase式を使用します。それによってグループ化されます。 – jarlh

+0

時間枠はどのようにまたはどこに定義されていますか?そこから、実際のクエリを導出することができる。 – Grayson

+0

フライトが正確に6:00にある場合は、時間枠を数えますか? – mathguy

答えて

1

グループは22:00から始まり、その後8時間の倍数になるので、TRUNC()と2時間のオフセットを使用して、毎日のグループ分けを得ることができます。

その後、出発はそのことでグループ内にもあり、一日のどの第三アウト作業することができます:このような何かが動作するはず

GROUP BY TRUNC(Departure + 2/24), 
     FLOOR((Departure + 2/24 - TRUNC(Departure + 2/24)) * 3) 
1

。 2つの入力変数、first_timetimespanに注意してください。 timespanはあなたが望むものであれば何でも構いません(私は8/24形式で書いていますが、timespanをHOURSで表される数値としてバインド変数にする場合は24で除算が必要です)。私が数式を書いた方法のために、first_timeの要件は境界日時の1つでなければならない。それは将来にあるかもしれないし、結果を変えないだろう。また、バインド変数にすることもできます。次に、どの形式でクエリを使用できるかを決めることができます。

with timetable (departure, flight, destination) as (
     select to_date('2016-06-01 10:12:00', 'yyyy-mm-dd hh24:mi:ss'), 'LH1234', 'New York' 
     from dual  union all 
     select to_date('2016-06-02 14:23:00', 'yyyy-mm-dd hh24:mi:ss'), 'LH1235', 'Berlin' 
     from dual  union all 
     select to_date('2016-06-02 14:30:00', 'yyyy-mm-dd hh24:mi:ss'), 'LH1236', 'Tokyo'  
     from dual  union all 
     select to_date('2016-06-03 18:45:00', 'yyyy-mm-dd hh24:mi:ss'), 'LH1237', 'Belgrad' 
     from dual  union all 
     select to_date('2016-06-04 04:10:00', 'yyyy-mm-dd hh24:mi:ss'), 'LH1237', 'Rio' 
     from dual  union all 
     select to_date('2016-06-04 06:20:00', 'yyyy-mm-dd hh24:mi:ss'), 'LH1237', 'Paris' 
     from dual 
    ), 
    input_values (first_time, timespan) as (
     select to_date('2010-01-01 06:00:00', 'yyyy-mm-dd hh24:mi:ss'), 8/24 from dual 
    ), 
    prep (adj_departure, flight, destination) as (
     select first_time + timespan * floor((departure - first_time)/timespan), 
       flight, destination 
     from timetable, input_values 
    ) 
select to_char(adj_departure, 'yyyy-mm-dd hh24:mi:ss') || ' - ' || 
      to_char(adj_departure + timespan, 'yyyy-mm-dd hh24:mi:ss') as time_interval, 
     count(*) as ct 
from prep, input_values 
group by adj_departure, timespan 
order by adj_departure 
; 

出力

TIME_INTERVAL          CT 
----------------------------------------- ---------- 
2016-06-01 06:00:00 - 2016-06-01 14:00:00   1 
2016-06-02 14:00:00 - 2016-06-02 22:00:00   2 
2016-06-03 14:00:00 - 2016-06-03 22:00:00   1 
2016-06-03 22:00:00 - 2016-06-04 06:00:00   1 
2016-06-04 06:00:00 - 2016-06-04 14:00:00   1 
関連する問題