2011-01-25 1 views
4

大量の個別クエリを作成するのではなく、時間を大幅に節約するために単一のクエリを作成しようとしましたが、これをどのように始めるべきかも知りません。SQL/Oracleのグループ化特定の日に特定のタイプのデータを時間でフィールド化する

私が必要としているのは、single day and typeを参照して、行動のカウントを時間単位で午前8時から午後8時までに分けます。だから、例えば私は

  • ですべてのレコードを見たい場合TYPE_ =だから、日2010-11-19
  • 上の「」
  • を次の表の偽

    TYPE_ ACTION_  TIMESTAMP_ 
    ------------------------------ 
    A  processed 2010-11-19 10:00:00.000 
    A  processed 2010-11-19 10:46:45.000 
    A  processed 2010-11-19 11:46:45.000 
    A  processed 2010-11-19 12:46:45.000 
    A  processed 2010-11-19 12:48:45.000 
    A  pending  2010-11-19 11:46:45.000 
    A  pending  2010-11-19 11:50:45.000 
    A  pending  2010-11-19 12:46:45.000 
    A  pending  2010-11-19 12:48:45.000 
    B  pending  2010-11-19 19:48:45.000 
    B  pending  2010-11-19 21:46:45.000 
    .etc 
    

    を持っています

毎時ACTION_によってグループ化された私は

この結果を見るでしょう
ACTION_ NUMOCCURENCES RANGE 
--------------------------------------------- 
processed 2    10:00:00 - 11:00:00 
pending 0    10:00:00 - 11:00:00 
processed 1    11:00:00 - 12:00:00 
pending 2    11:00:00 - 12:00:00 
processed 2    12:00:00 - 13:00:00 
pending 2    12:00:00 - 13:00:00 

またはこれに類似したものですが、少なくとも私が探しているもののアイデアを与える必要があります。

誰でも手助けできますか?通常、私は作業しているいくつかのサンプルコードを提供しようとしますが、これを実現するために必要な節ごとの作業方法はわかりません。今

+0

DDLとINSERTを提供できますか? – Chandu

答えて

7
select 
    action_, 
    count(*) as numoccurences, 
    to_char(timestamp_  , 'hh24') || ':00:00-' || 
    to_char(timestamp_ + 1/24, 'hh24') || ':00:00' as range 
from 
    tq84_action 
where 
    timestamp_ between timestamp '2010-11-19 08:00:00' and 
         timestamp '2010-11-19 20:00:00' and 
    type_ = 'A' 
group by 
    action_, 
    to_char(timestamp_  , 'hh24') || ':00:00-' || 
    to_char(timestamp_ + 1/24, 'hh24') || ':00:00' 
order by 
    range; 

、上記のSELECT文は唯一のアクションに少なくともありする時間を返します。すべての時間のレコードを表示するためには - {/処理保留中}の組み合わせは、以下の改正は、クエリになされるべきである。

select 
    action_, 
    count(type_) as numoccurences, 
    to_char(timestamp_  , 'hh24') || ':00:00-' || 
    to_char(timestamp_ + 1/24, 'hh24') || ':00:00' as range_ 
from (
    select * from tq84_action 
    where 
     timestamp_ between timestamp '2010-11-19 08:00:00' and 
         timestamp '2010-11-19 20:00:00' and 
     type_ = 'A' 
    union all (
     select 
     null as type_, 
     action.name_ as action_, 
     date '2010-11-19' + 8/24 + hour.counter_/24 as timestamp_1 
     from (
     select 
      level-1 counter_ 
     from dual 
      connect by level <= 12 
    ) hour, 
     ( 
     select 'processed' as name_ from dual union all 
     select 'pending' as name_ from dual 
    ) action 
    ) 
) 
group by 
    action_, 
    to_char(timestamp_  , 'hh24') || ':00:00-' || 
    to_char(timestamp_ + 1/24, 'hh24') || ':00:00' 
order by 
    range_; 

ところで、ここではDDLとDMLは、私が使用します:

drop table tq84_action; 
create table tq84_action (
    type_  varchar2(1), 
    action_ varchar2(10), 
    timestamp_ timestamp 
); 


insert into tq84_action values('A', 'processed' , timestamp '2010-11-19 10:00:00.000'); 
insert into tq84_action values('A', 'processed' , timestamp '2010-11-19 10:46:45.000'); 
insert into tq84_action values('A', 'processed' , timestamp '2010-11-19 11:46:45.000'); 
insert into tq84_action values('A', 'processed' , timestamp '2010-11-19 12:46:45.000'); 
insert into tq84_action values('A', 'processed' , timestamp '2010-11-19 12:48:45.000'); 
insert into tq84_action values('A', 'pending' , timestamp '2010-11-19 11:46:45.000'); 
insert into tq84_action values('A', 'pending' , timestamp '2010-11-19 11:50:45.000'); 
insert into tq84_action values('A', 'pending' , timestamp '2010-11-19 12:46:45.000'); 
insert into tq84_action values('A', 'pending' , timestamp '2010-11-19 12:48:45.000'); 
insert into tq84_action values('B', 'pending' , timestamp '2010-11-19 19:48:45.000'); 
insert into tq84_action values('B', 'pending' , timestamp '2010-11-19 21:46:45.000'); 
+0

'と1 * to_char(TIMESTAMP_、 'hh24')の間の8と19の間の時間のフィルター? – RichardTheKiwi

+0

すごい速かった!残念ながら、これは、Oracleが "GROUP BYの式ではない"と私に語りかけるものです。 – dscl

+0

はい、あなたは正しいですし、Oracleもそうです。 'order by range'を読んでください。回答が更新されました。 –

3
select 
    ACTION_ 
    count(*) NUMOCCURENCES, 
    to_char(TIMESTAMP_, 'hh24') || ':00:00 - ' || to_char(TIMESTAMP_ + 1/24, 'hh24') || ':00:00' RANGE 
from tbl 
where TIMESTAMP_ between DATE '2010-11-19' and DATE '2010-11-20' 
    and TYPE_ = 'A' 
    and 1 * to_char(TIMESTAMP_, 'hh24') between 8 and 19 
group by ACTION_, to_char(TIMESTAMP_, 'hh24'), to_char(TIMESTAMP_ + 1/24, 'hh24') 
order by RANGE, ACTION_ desc 
+0

+1は午前8時と午後8時にレコードを制限します。 –

関連する問題