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

似乎您希望在每个案例语句周围使用 sum() 聚合值并按 table_id 分组,但是既然您询问了查询优化...

如果 closed_ts 上有索引,您将无法使用它,因为您正在截断它。截断 closed_ts 日期是不必要的,因为您正在检查它是否严格大于日、周、月、年,所以这个查询肯定会导致全表扫描。

无论在 closed_ts 上是否有索引,我都可能会在没有 trunc 的情况下重写它:

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 回答
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 回答