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

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

Related

How to get MAX Hike in Min month?

below is table:
Name | Hike% | Month
------------------------
A 7 1
A 6 2
A 8 3
b 4 1
b 7 2
b 7 3
Result should be:
Name | Hike% | Month
------------------------
A 8 3
b 7 2
Here is one way of doing this:
SELECT Name, [Hike%], Month
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY [Hike%] DESC, Month) rn
FROM yourTable
) t
WHERE rn = 1
ORDER BY Name;
If you instead want to return multiple records per name, in the case where two or more records might be tied for having the greatest hike%, then replace ROW_NUMBER with RANK.
use correlated subquery
select Name,min(Hike) as Hike,min(Month) as Month
from
(
select * from tablename a
where Hike in (select max(Hike) from tablename b where a.name=b.name)
)A group by Name
You can use something similar to the below:
SELECT Name, MAX(Hike), Month
FROM table
GROUP BY Name, Month
Hope this helps :)

sql - select single ID for each group with the lowest value

Consider the following table:
ID GroupId Rank
1 1 1
2 1 2
3 1 1
4 2 10
5 2 1
6 3 1
7 4 5
I need an sql (for MS-SQL) select query selecting a single Id for each group with the lowest rank. Each group needs to only return a single ID, even if there are two with the same rank (as 1 and 2 do in the above table). I've tried to select the min value, but the requirement that only one be returned, and the value to be returned is the ID column, is throwing me.
Does anyone know how to do this?
Use row_number():
select t.*
from (select t.*,
row_number() over (partition by groupid order by rank) as seqnum
from t
) t
where seqnum = 1;

Get specified row ranking number

Here is the rows looks like:
Id Gold
1 200
2 100
3 300
4 900
5 800
6 1000
What I want to achieve is getting the rank number whose Id equals to 5, which is order by Gold descending.
So after ordering, the intermediate rows should be(NOT RETURN):
Id Gold
6 1000
4 900
5 800
And the SQL should just return 3, which is the ranking of Id = 5 row.
What is the most efficient way to achieve this?
You simply want top, I think:
select top 3 t.*
from t
order by gold desc;
If you want the ranking of id = 5:
select count(*)
from t
where t.gold >= (select t2.gold from t t2 where t2.id = 5);
Try This Code By using Dense_rank():
WITH cte
AS (SELECT *,
Dense_rank()
OVER(
ORDER BY [Gold] DESC) AS rank
FROM your_table)
SELECT rank
FROM cte
WHERE id = 5

MAX function without group by

I have the following table:
ID | NUM
1 | 4
2 | 9
3 | 1
4 | 7
5 | 10
I want a result of:
ID | NUM
5 | 10
When I try to use MAX(NUM) I get and error that I have to use GROUP BY in order to use MAX function
Any idea?
As per the error, use of an aggregate like Max requires a Group By clause if there are any non-aggregated columns in the select list (In your case, you are trying to find the MAX(Num) and then return the value(s) associated in the ID column). In MS SQL Server you can get what you want via ordering and limiting the returned rows:
SELECT TOP 1 ID, NUM
FROM [table]
ORDER BY NUM DESC;
In other RDBMS systems the LIMIT offers similar functionality.
Edit
If you need to return all rows which have the same maximum, then use the WITH TIES qualification:
SELECT TOP 1 WITH TIES ID, NUM
FROM [table]
ORDER BY NUM DESC;
May return more than 1 result:
SELECT id, num
FROM table
WHERE num = (SELECT MAX(num) FROM table)
Try this query.
WITH result AS
(
select DENSE_RANK() OVER( ORDER BY NUM desc) AS RowNo,ID,NUM from #emp
)
select ID,NUM from result where RowNo=1
it will return max values even if it has more MAX values like:
ID | NUM
5 | 10
6 | 10
refer below link to know more about RANKING Functions:
http://msdn.microsoft.com/en-us/library/ms189798
How about:
SELECT TOP 1 ID,NUM FROM table ORDER BY NUM DESC;
Do this -
SELECT TOP 1 ID,
NUM
FROM <yourtable>
ORDER BY NUM DESC;
Get all rows have max values but THERE ARE 3 SELECT, It's not good for performance
SELECT id, MAX(num) as num
FROM table
GROUP BY id
ORDER BY MAX(num) DESC
LIMIT (SELECT COUNT(*)
FROM table
WHERE num =(SELECT MAX(num) FROM table)
)

TOP 1 Query from each ID with multiple instances

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