SQL get values with MAX date by grouping - sql

I have database with columns:
station, source, type, date and price
I would like to get newest price for each type.
I tried
SELECT max(date) and GROUP BY station, source, type
but error appears "price must appear in GROUP BY clause"
May be someone know how to do it?

If you want the most recent row for a combination of columns, you can use row_number():
select t.*
from (select t.*,
row_number() over (partition by station, source, type order by date desc) as seqnum
from t
) t
where seqnum = 1;

You can try the below one-
select * from
(
SELECT station, source, type ,price, row_number() over(partition by type order by date desc) as rn from tablename
)A where rn=1

Related

SUM most recent ID/Product combinations for the latest date

select * from
(select Id, Prodcut, Billing_date
, row_number() over (partition by Id, product order by Billing_date desc) as RowNumber
,sum(Revenue)
from Table1
group by 1,2,3,4,1) a
where a.rowNumber = 1
There are rows where Id+product combination repeats for latest billing date and which causing some data to be missed out. I am trying to add sum with row_number to sum all the ID&product combinations for the latest date but not able to make it work.
Can anyone please help me out here!
Data Sample Image
Database: Athena, Dbeaver
I would expect this to do what you want:
select *
from (select Id, Product, Billing_date,
row_number() over (partition by Id, product order by Billing_date desc) as seqnum,
sum(Revenue)
from Table1
group by Id, Product, Billing_date
) t1
where seqnum = 1;
Your group by columns do not seem correct. I'm surprised your query runs in any datbase.

Select MIN MAX together alters behaviour of query

I have a SQLite table with the following columns:
timestamp
id
value
I want to write a query that - for each id - lists the latest timestamp with the value at that timestamp, as well as the max value for each id.
For that I wrote the following query that works as expected.
SELECT timestamp, MAX(value) as max, id, value from (
SELECT * from temperatures order by timestamp DESC
) GROUP BY ID;
When I now also want to calculate the min value, I alter the query:
SELECT timestamp, MAX(value) as max, MIN(value) as min, id, value from (
SELECT * from temperatures order by timestamp DESC
) GROUP BY ID;
The problem now is that the timestamp is not the latest timestamp anymore. Why is that?
Your query is malformed. The SELECT list is not compatible with the GROUP BY. So, what SQLite does is bespoke processing . . . and yes, what the query does change the meaning by adding another column.
I would recommend that you write the query using window functions:
SELECT id, MIN(timestamp), MAX(timestamp),
MIN(CASE WHEN timestamp_asc = 1 THEN value END) as temp_at_min,
MIN(CASE WHEN timestamp_desc = 1 THEN value END) as temp_at_max
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp ASC) as seqnum_asc,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp ASC) as seqnum_desc
FROM temperatures t
) t
GROUP BY ID;
This is standard SQL and should consistently do what you want.
You can do it with MIN(), MAX() and FIRST_VALUE() window functions:
SELECT DISTINCT id,
MIN(timestamp) OVER (PARTITION BY id) min_timestamp,
MAX(timestamp) OVER (PARTITION BY id) max_timestamp,
FIRST_VALUE(value) OVER (PARTITION BY id ORDER BY timestamp) min,
FIRST_VALUE(value) OVER (PARTITION BY id ORDER BY timestamp DESC) max
FROM temperatures
There is no need for aggregation, window functions are enough.

How to retriever the First Record and Last Record in the Group, for Same Date, In Oracle SQL

Please Suggest me, I have tried with Partition and group in Oracle SQL, but unable to get the right query
One option uses row_number() twice:
select primary_key, id, created_date
from (
select
t.*,
row_number() over(partition by id, trunc(created_date) order by created_date asc) rn_asc,
row_number() over(partition by id, trunc(created_date) order by created_date desc) rn_desc
from mytable t
) t
where 1 in (rn_asc, rn_desc)

SQL Finding five largest numbers instead of one Max in a table

I have a table and I need to run a query that contains some aggregation Functions like Maximum , Average , Standard Deviation , ...
but instead of one Maximum I should return 5 largest number.
the simplified query is something like this:
SELECT OSI_KEY , MAX(VALUE) , AVG(VALUE) , STDDEV(VALUE), variance(VALUE)
FROM DATA_VALUES_5MIN_6_2013
GROUP BY OSI_KEY
ORDER BY OSI_KEY
and I need some Magical ;) Query like this:
SELECT OSI_KEY , MAX1(VALUE) ,MAX2(VALUE) ,MAX3(VALUE) ,MAX4(VALUE) , MAX5(VALUE) ,
AVG(VALUE) , STDDEV(VALUE), variance(VALUE)
FROM DATA_VALUES_5MIN_6_2013
GROUP BY OSI_KEY
ORDER BY OSI_KEY
I appreciate your considerations.
Oracle has an NTH_VALUE() function. Unfortunately, it is only an analytic function and not a window function. This leads to the strange construct of SELECT DISTINCT with a bunch of analytic functions:
SELECT DISTINCT OSI_KEY,
MAX(VALUE) OVER (PARTITION BY OSI_KEY),
NTH_VALUE(VALUE, 2) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_2,
NTH_VALUE(VALUE, 3) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_3,
NTH_VALUE(VALUE, 4) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_4,
NTH_VALUE(VALUE, 5) OVER (PARTITION BY OSI_KEY ORDER BY VALUE DESC) as MAX_5,
AVG(VALUE) OVER (PARTITION BY OSI_KEY),
STDDEV(VALUE) OVER (PARTITION BY OSI_KEY),
variance(VALUE) OVER (PARTITION BY OSI_KEY)
FROM DATA_VALUES_5MIN_6_2013
ORDER BY OSI_KEY;
You can also do this using conditional aggregation, with a row_number() or dense_rank() in a subquery.
SELECT OSI_KEY, MaxValue FROM (
SELECT OSI_KEY, MAX(value) AS MaxValue FROM table GROUP BY OSI_KEY
)
ORDER BY MaxValue DESC
FETCH FIRST 5 ROWS ONLY;

How to get single closest value for each column type in DB2

I have this query:
SELECT * FROM TABLE1 WHERE KEY_COLUMN='NJCRF' AND TYPE_COLUMN IN ('SCORE1', 'SCORE2', 'SCORE3') AND DATE_EFFECTIVE_COLUMN<='2016-09-17'
I get about 12 record(rows) as result.
How to get result closest to DATE_EFFECTIVE_COLUMN for each TYPE_COLUMN? In this case, how to get three records, for each type, that are closest to effective date?
UPDATE: I could use TOP if I had to go over only single type, but I have three at this moment and for each of them I need to get closest time result.
Hope I made it clear, let me know if you need more info.
If I understand correctly, you can use ROW_NUMBER():
SELECT t.*
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY TYPE_COLUMN ORDER BY DATE_EFFECTIVE_COLUMN DESC) as seqnum
FROM TABLE1 t
WHERE KEY_COLUMN = 'NJCRF' AND
TYPE_COLUMN IN ('SCORE1', 'SCORE2', 'SCORE3') AND
DATE_EFFECTIVE_COLUMN <= '2016-09-17'
) t
WHERE seqnum = 1;
If you want three records per type, just use seqnum <= 3.
I like ROW_NUMBER() for this. You want to partition by TYPE, which will start the row count over for each type, then order by DATE_EFFECTIVE desc, and take only the highest date (the first row):
SELECT *
FROM (
SELECT *,
ROW_NUMBER() over (PARTITION BY TYPE_COLUMN ORDER BY DATE_EFFECTIVE_COLUMN desc) RN
FROM TABLE1
WHERE KEY_COLUMN = 'NJCRF'
AND TYPE_COLUMN IN ('SCORE1', 'SCORE2', 'SCORE3')
AND DATE_EFFECTIVE_COLUMN <= '2016-09-17'
) A
WHERE RN = 1