Reputation: 745
So i have a table called Value. This table has columns called: VALUE_ID, VALUE, HR, VALUE_TYPE. I am trying to grab not only the maximum value but also the HR (and ultimately the day) that the Maximum Value Occurred.
Below is some sample data:
VALUE_ID VALUE HR VALUE_TYPE
1 75 DEC-25-2018 01:00:00 AM Bananas
2 10 DEC-25-2018 01:00:00 AM Bananas
3 787 DEC-25-2018 05:00:00 PM Bananas
I want:
(For Hourly)
MAX(Value) HR Value_Type
75 DEC-25-2018 01:00:00 AM Bananas
787 DEC-25-2018 05:00:00 PM Bananas
(For Day)
MAX(Value) HR(Day) Value_Type
787 DEC-25-2018 05:00:00 PM Bananas
I've tried the following (this is probably completely wrong but im not sure how to combine columns from two separate queries into one table):
select max(value) as max_value
, Value_Type
from value
group by value_type
UNION
select HR from
from value
where value = (select max(value) as max_value
, Value_Type
from value
group by value_type;
Thanks in advance.
Upvotes: 1
Views: 395
Reputation:
Analytic functions are perfect for this kind of question. They allow the base data to be read just once (rather than multiple times, as in solutions that aggregate, then compare to the original data).
In the sample session below, notice a few things. I create some sample data in a WITH
clause (which you don't need, you have the actual table). I use the TO_DATE
function to create dates. So that I don't need to write the format model multiple times, I first alter my session to set the default date format to the one you used.
The query is written for the hourly intervals; you can modify it easily for daily, by changing the argument to TRUNC()
in the inner query, from 'hh'
to 'dd'
. If you are new to analytic functions, select and run the inner query by itself first, to see what it produces. Then it will be trivial to understand what the outer query does.
alter session set nls_date_format = 'MON-dd-yyyy hh:mi:ss AM';
with simulated_table (VALUE_ID, VALUE, HR, VALUE_TYPE) as (
select 1, 75, to_date('DEC-25-2018 01:00:00 AM'), 'Bananas' from dual union all
select 2, 10, to_date('DEC-25-2018 01:00:00 AM'), 'Bananas' from dual union all
select 3, 787, to_date('DEC-25-2018 05:00:00 PM'), 'Bananas' from dual
)
select value_id, value, hr, value_type
from (
select s.*,
max(value) over (partition by value_type, trunc(hr, 'hh')) maxval
from simulated_table s
)
where value = maxval
;
VALUE_ID VALUE HR VALUE_TYPE
---------- ---------- ----------------------- ----------
1 75 DEC-25-2018 01:00:00 AM Bananas
3 787 DEC-25-2018 05:00:00 PM Bananas
Upvotes: 2
Reputation: 1269443
You could do:
select v.*
from value v
where v.value = (select max(v2.value)
from value v2
where trunc(v2.hr, 'HH')= trunc(v.hr, 'HH')
) or
v.value = (select max(v2.value)
from value v2
where trunc(v2.hr, 'DD')= trunc(v.hr, 'DD')
) ;
This gets the maximum value rows for both the hour and the day. You can use one clause or the other for just hours or just days.
Upvotes: 2