I have a bunch of queries that take data with a time stamp and spit out SUMS based the last few weeks, months, and year to date. It looks like this
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
This is how the query currently does this
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
Is there a better way in Oracle?
I think you are looking for something like this:
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;
Note that you won't need the WITH block, I was just using it to create some dummy data. The Ord column might be unnecessary for you, I was just using it to order the data in a logical fashion.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.