TOP 1 Query from each ID with multiple instances - sql

This query will return the top for all rows in MS Access.
SELECT TOP 1 * FROM [table]
ORDER BY table.[Date] DESC;
I need to return the top date for each id that can have multiple dates.
ID DATE
1 01/01/2001
1 01/12/2011
3 01/01/2001
3 01/12/2011
Should return only the top dates like this.
1 01/12/2011
3 01/12/2011

You'll want to use the MAX function, along with a GROUP BY.
SELECT ID, MAX(DATE)
FROM [table]
GROUP BY ID

Related

how to get row value with group by clause using subquery in PostgreSQL in Laravel 8?

This is my table, first I want to get status_exec of each MAX (date_sta) and after that I want to grouped by status_exec and get the COUNT.
id_out_sta
status_exec
date_sta
1
2
2021-11-07
1
1
2021-11-28
1
5
2021-12-07
2
7
2021-04-02
2
2
2021-05-12
2
6
2021-08-07
3
2
2021-08-05
3
5
2021-08-28
4
2
2021-03-15
4
5
2021-04-25
The result I would expect should be the following:
status_exec
COUNT
5
3
6
1
This is my query but it didn't help:
SELECT id_out_sta, status_exec , max(date_sta) as max_date_sta
FROM public.status_exe
join public.order_out on status_exe.id_out_sta = order_out.id_out
group by (id_out_sta);
Please any suggestion, query builder or simple query.
A common solution for this is row_number window function to find the maximum of each group. Using this in a CTE and then aggregating the result:
with s as (
select *,
Row_Number() over(partition by id_out_sta order by max_date_sta desc) rn
from t
)
select status_exec, Count(*) "Count"
from s
where rn=1
group by status_exec
Example DB<>Fiddle
Using DISTINCT ON followed by a subquery:
SELECT status_exec, COUNT(*) AS COUNT
FROM
(
SELECT DISTINCT ON (status_exec) *
FROM public.status_exe
ORDER BY status_exec, max_date_sta DESC
) t
GROUP BY status_exec;
Here is another example by using count window function.
SELECT * FROM (
SELECT DISTINCT ON (id_out_sta)
status_exec,
count(*) over(partition by status_exec)
FROM t
ORDER BY id_out_sta, max_date_sta DESC
) as list
GROUP BY 1,2
Fiddle is here

Postgres query with limit that selects all records with similar identifier

I have a table that looks something like this:
customer_id
data
1
123
1
456
2
789
2
101
2
121
2
123
3
123
4
456
What I would like to do is perform a SELECT combined with a LIMIT X to get X number of records as well as any other records that have the same customer_id
Example query: SELECT customer_id, data FROM table ORDER BY customer_id LIMIT 3;
This query returns:
customer_id
data
1
123
1
456
2
789
I'd like a query that will look at the last customer_id value and return all remaining records that match beyond the LIMIT specified. Is it possible to do this in a single operation?
Desired output:
customer_id
data
1
123
1
456
2
789
2
101
2
121
2
123
In Postgres 13 can use with ties:
select t.*
from t
order by customer_id
fetch first 3 rows with ties;
In earlier versions you can use in:
select t.*
from t
where t.customer_id in (select t2.customer_id
from t t2
order by t2.customer_id
limit 3
);
You can use corelated subquery with count as follows:
Select t.*
From t
Where 3 >= (select count(distinct customer_id)
From t tt
where t.customer_id >= tt.customer_id)

SQL Sorted Count

I have the following table sorted by date:
date
id
9/1/20
1
9/1/20
2
9/3/20
1
9/4/20
3
9/4/20
2
9/6/20
1
I'd like to add a count column for each id so that the first count for each id is the earliest date and latest date would receive the highest count for each id:
date
id
count
9/1/20
1
1
9/1/20
2
1
9/3/20
1
2
9/4/20
3
1
9/4/20
2
2
9/6/20
1
3
How can I structure my Postgresql query to assemble this count column?
This looks like row_number():
select t.*,
row_number() over (partition by id order by date) as seqnum
from t
order by date, id;

SQL left join with 2 or more count group

My table
ID catone cattwo
100 2 1
100 3 1
200 1 2
expect result (count not sum)
ID totalcat1 totalcat2
100 2 2
200 1 1
My query
select COUNT(*) as totalcat1, catone
from Table1
group by cat1
left join
select COUNT(*) as totalcat2, cattwo
from Table1
group by cattwo
Try to have both count columns catone and cattwo
Not sure how to correct it. Thank you
A simple group-by should do it
select ID, COUNT(catone) as totalcat1, COUNT(cattwo) as totalcat2
from Table1
group by ID;
Note that this simply counts the number of values that are not NULL. If your original data was this...
ID catone cattwo
100 2 1
100 3 1
100 4 NULL
... then the result would be
ID totalcat1 totalcat2
100 3 2
If you want to count the distinct values - so totalcat2 would be 1 (as only 1 value exists in that column, although it's there twice) you could use
select ID, COUNT(DISTINCT catone) as totalcat1, COUNT(DISTINCT cattwo) as totalcat2
from Table1
group by ID;
which would return totalcat1 = 3 and totalcat2 = 1.
Here's a db<>fiddle with the two options.
Here's a second db<>fiddle on request of OP with ID 200.

How to use a select command to find all the records that has the maximum date value for a specific item?

Say I have a table like this, we call it tbl_test
ID thedate actionid songid
1 2014-10-01 100 10
2 2014-09-30 100 10
3 2014-10-01 80 10
4 2014-09-30 80 10
5 2014-10-01 80 21
6 2014-09-30 100 21
Now I want to find all the record thats in the tbl_test where actionid=100 and with the latest [thedate] value. In this case, I want the final select result to be
(this is the result I want, not an existing table)
ID thedate actionid songid
1 2014-10-01 100 10
6 2014-09-30 100 21
Question, how am I going to do that use nothing but a single select command in MS SQL Server?
Use a join to a query that returns the latest date for each song:
select tbl_test.*
from tbl_test
join (select songid, max(theDate) maxDate
from tbl_test
where actionId = 100
group by songid) t on t.songId = tbl_test.songId and theDate = maxDate
where actionid = 100
This should perform pretty well as it makes only 2 passes over the table - one for the inner query that determines the latest date, and another to output the matching rows
A general SQL way to get this is using not exists:
select t.*
from tbl_test t
where actionid = 100 and
not exists (select 1
from tbl_test t2
where t2.songid = t.songid and t2.actionid = 100 and t2.thedate > t.thedate
);
For performance, you want an index on songid, actionid, thedate.