0

これがクエリです。closed_ts はタイムスタンプ列です。私がやろうとしているのは、今日、今月、今年、今週のどれだけが「閉鎖」されたかを調べることです。これを行うより良い方法はありますか?

select table_id,
  case
    when trunc(closed_ts) = trunc(SYSDATE, 'DD') then 1
    else 0
  end as day_count,
  case
    when trunc(closed_ts) >= trunc(SYSDATE, 'MM') then 1
    else 0
  end as month_count,
 case
   when trunc(closed_ts) >= trunc(sysdate, 'YYYY') then 1
   else 0
 end as year_count,
 case
   when trunc(closed_ts) >= TRUNC(sysdate, 'IW') then 1
   else 0
 end as week_count
from myTable
4

2 に答える 2

0

(closed_ts,table_id) にインデックスをポップし、以下のように closed_ts に述語を適用します ...

 select
   table_id,
   sum(case when closed_ts >= trunc(SYSDATE,'DD'  ) then 1 end) day_count,
   sum(case when closed_ts >= trunc(SYSDATE,'MM'  ) then 1 end) month_count,
   sum(case when closed_ts >= trunc(SYSDATE,'YYYY') then 1 end) year_count,
   sum(case when closed_ts >= trunc(SYSDATE,'IW'  ) then 1 end) week_count,
 from
   myTable
 where
   closed_ts >= least(trunc(SYSDATE,'YYYY'),trunc(SYSDATE,'IW'))
 group by
   table_id

user1842757 が述べたように、closed_ts の trunc を失います。case ステートメントで ELSE 0 を失うこともあります

于 2012-11-21T21:20:09.827 に答える
0

各 case ステートメントの周りに sum() を使用して値を集計し、table_id でグループ化したいようですが、クエリの最適化について尋ねたので...

closed_ts にインデックスがある場合、切り捨てているため使用できません。日付が日、週、月、年よりも厳密に大きいかどうかを確認しているため、closed_ts の日付を切り捨てる必要はありません。したがって、このクエリでは間違いなく完全なテーブル スキャンが実行されます。

closed_ts にインデックスがあったかどうかに関係なく、切り捨てなしで書き直す可能性があります。

select table_id
      ,sum(case when closed_ts >= trunc(sysdate) then 1 else 0 end) as day_count
      ,sum(case when closed_ts >= trunc(sysdate,'MM') then 1 else 0 end) as month_count
      ,sum(case when closed_ts >= trunc(sysdate,'YYYY') then 1 else 0 end) as year_count
      ,sum(case when closed_ts >= trunc(sysdate,'IW') then 1 else 0 end) as week_count
 from myTable
group by table_id

ところで: table_id はプライマリ キーまたはサロゲート キーのように聞こえますが、結果にそれが必要ですか?

于 2012-11-21T17:20:48.693 に答える