我有一堆查询带有时间戳的数据,并根据最近几周,几个月和一年的时间吐出SUMS。看起来像这样
Week1 Sum for most recent week
Week2 Sum for second most recent week
WeekN Sum for N most recent week
Jan-Dec Sum for January-December
YTD Sum for everything this year
这是查询当前执行此操作的方式
SELECT TIME_PERIOD, INDEX, SUM(ITEM)
FROM (SELECT
INDEX ,
(CASE
WHEN ACTIVITY_DAY>=(TO_DATE( :end_day,
'yyyy-mm-dd' )-6)
AND ACTIVITY_DAY<=(TO_DATE( :end_day,
'yyyy-mm-dd' )-0) THEN 'WEEK1'
WHEN ACTIVITY_DAY>=(TO_DATE( :end_day,
'yyyy-mm-dd' )-13)
AND ACTIVITY_DAY<=(TO_DATE( :end_day,
'yyyy-mm-dd' )-7) THEN 'WEEK2'
ELSE NULL
END) AS TIME_PERIOD,
MAX(ITEMS) AS ITEM
FROM
SOURCE
GROUP BY
INDEX ,
DAY
UNION
ALL SELECT
INDEX ,
(CASE
WHEN ACTIVITY_DAY>=TO_DATE( :year||'-01-01',
'yyyy-mm-dd' )
AND ACTIVITY_DAY<=TO_DATE( :year||'-01-31',
'yyyy-mm-dd' ) THEN 'Jan'
WHEN ACTIVITY_DAY>=TO_DATE( :year||'-02-01',
'yyyy-mm-dd' )
AND ACTIVITY_DAY<TO_DATE( :year||'-03-01',
'yyyy-mm-dd' ) THEN 'Feb'
ELSE NULL
END) AS TIME_PERIOD ,
MAX(ITEMS) AS ITEM
FROM
SOURCE
GROUP BY
INDEX ,
DAY
UNION
ALL SELECT
INDEX ,
(CASE
WHEN ACTIVITY_DAY>=TO_DATE( :year||'-01-01',
'yyyy-mm-dd' )
AND ACTIVITY_DAY<=TO_DATE( :end_day,
'yyyy-mm-dd' ) THEN 'YTD'
ELSE NULL
END) AS TIME_PERIOD,
MAX(ITEMS) AS ITEM
FROM
SOURCE
GROUP BY
INDEX ,
DAY)
GROUP BY INDEX, TIME_PERIOD
Oracle中有更好的方法吗?
答案 0 :(得分:1)
我认为你正在寻找这样的东西:
with data as
(
select sysdate - floor(dbms_random.value(1,400)) dt, floor(dbms_random.value(1,100)) val
from dual
connect by level <= 100
)
select
time_period,
sum(val) period_sum
from
(
select -- weeks
'Week'||(to_char(sysdate, 'WW') - to_char(dt, 'WW') + 1) time_period,
val,
(to_char(sysdate, 'WW') - to_char(dt, 'WW') + 1) ord
from data
where dt >= trunc(sysdate,'YY')
union all
select -- months
to_char(dt, 'Mon') time_period,
val,
100+to_char(dt,'MM') ord
from data
where dt >= trunc(sysdate,'YY')
union all
select -- months
'YTD' time_period,
val,
200
from data
where dt >= trunc(sysdate,'YY')
)
group by
time_period, ord
order by
ord;
请注意,您不需要WITH块,我只是用它来创建一些虚拟数据。 Ord列对您来说可能是不必要的,我只是用它来以逻辑方式对数据进行排序。