0

次の列に結果を表示するSQLコマンドがあります

start_date, end_date, count, weekday

start_date ごとに、start_date から平日が一致する end_date までのカウントの合計を取得したいと考えています。

たとえば、start_date = 2012 01 01andend_date = 2012 08 08と をweekday = Tuesday含む行がある場合、 start_date がその範囲内にあり、火曜日である他のすべての行を見つけてから、カウントの合計を見つけます。どうすればそれを達成できますか?

例 この表から

Start       ||  End         ||Count||  Weekday
2012-01-01  ||  2012-12-12  ||  5  ||  Tuesday
2012-05-05  ||  2012-12-12  ||  7  ||  Tuesday
2012-06-06  ||  2012-10-10  ||  2  ||  Wednesday
2012-07-07  ||  2012-08-08  ||  8  ||  Wednesday
2012-09-09  ||  2012-10-10  ||  9  ||  Tuesday

返すべき

date        |  sum_count
2012-01-01  |  16    // count of 2012-05-05 + 2012-09-09 (Tuesdays only)
2012-05-05  |  9
2012-06-06  |  8
2012-07-07  |  0
2012-09-09  |  0
4

3 に答える 3

1

フィドルがなければ、sqlfiddle.comを最初の試行で正しく取得するのは難しいでしょう。しかし、あなたがやりたいことは、これらの行に沿ったものです:

   select count(*), * 
   from  
   (
    select *  
    from  
       (  
           select start_date,end_date,weekday  
           from  table  
           where start_date >= timestamp('2012 01 01')  
           and end_date <=  timestamp('2012 08 08')  
        )  
       where weekday = 'Tuesday'  
    );

目的は、毎回結果セットを減らすことweekdayです。個別のサブクエリを保持することで、コストのかかる結合または 2 を回避できる可能性があります。

質問

は?私はまだ理解していません。2012 08 08、2012 01 01 および Tuesday は入力テーブルからのもので、処理が必要な行が複数あります。各行を個別に処理する方が効率的だとおっしゃっていますか?

日付を検索するときにテーブル全体のスキャンを回避する方法がわかっている場合を除き、各行を個別に処理する必要があります。これは、説明計画を比較することにかかっていますが、まだあなたのフィドルを待っているため、私たちにはありません。
これの鍵は、最も内側のクエリが、必要な日付範囲と、すべての曜日を提供することです。より具体的な where 句 (この場合は曜日) に対して実行する方が効率的です (ほとんどの場合)。その理由は、データベース (ほとんどの最近のデータベースはこれを行っています) が、データをできるだけ早く返すことができるようにデータを並べ替えようとするためです。

余分な更新

これの実例として、分析関数を実行する必要がある 10 億近いエントリを持つテーブルがあります。私がこれを行った最初の方法は次のとおりです。

select *   
from  
(  
        select *, row_number() over (partition by id order by seen desc) rn  
        from foo  
)where rn =1  
 and status = 1

上記の実行には約 9 分かかります。クエリを次のように変更したとき:

select *
from   
(   select *   
    from  
    (  
            select *, row_number() over (partition by id order by seen desc) rn  
            from foo  
    )where status = 1  
) where status = 1

1分弱で戻ります。これは、駆動結果セットのサイズを慎重に縮小した例です。これにより、システムが行う作業が減り、より迅速に戻るようになります。

于 2012-12-19T16:29:06.417 に答える
1

これを試してみてください。自己参加が最良のオプションだと思います

  select b.start_date,nvl(sum(a.Count),0) from TABLE2 a right join TABLE2 b on 
  a.start_date<>b.start_date and
  a.weekday=b.weekday and a.start_date between b.start_date and b.end_date 
  group by b.start_date order by b.start_date  

フィドルデモ

于 2012-12-19T16:29:37.867 に答える
1

私はこれがあなたの要件であることを願っています...これはあなたのサンプルデータでオラクルで動作します

  select TAB.START_DATE START_DATE, nvl(X1.SUM_COUNT,0) SUM_COUNT
     from TABLE2 TAB,
        ( select A1.START_DATE,SUM(A2.COUNT) SUM_COUNT
          from TABLE2 A1,TABLE2 A2
          where A1.WEEKDAY=A2.WEEKDAY and A1.rowid <> A2.rowid
          and A2.START_DATE between A1.START_DATE and A1.END_DATE
          group by A1.START_DATE
       ) X1
    where TAB.START_DATE=X1.START_DATE(+) order by 1

この sql フィドルを参照してください: http://sqlfiddle.com/#!4/2019f/4

于 2012-12-20T12:25:17.023 に答える