Get ID of row from max value - sql

I'm new in database
I have the following table:
id group factor
------------------------
1 11 1
2 11 5
4 11 2
5 12 3
6 12 2
7 13 4
8 13 1
9 13 8
10 14 6
I need to get the id of the one that has the largest factor based on its group, for example, in the case of group 11, the row with the largest factor is 5, so I need to obtain the id of that row, in this case 2.
please if someone can show me the right way.

You could use:
SELECT DISTINCT ON(group) group factor, id
FROM tab
ORDER BY group, factor DESC;
db<>fiddle demo

You can use simple CTE (Common Table Expression) for it, as in:
with
x as (
select group_id, max(factor) as max_factor from my_table group by group_id
)
select t.*
from my_table t
join x on x.group_id = t.group_id and x.max_factor = t.factor
This solution has the [desirable?] feature that in case there are multiple rows tied in first place in the same group, it will show them all, not just one [randomly] of them.

If you know the group in advance, e.g. 11, then you can simply do:
SELECT id
FROM tab
WHERE group = 11
ORDER BY factor DESC
LIMIT 1;
Otherwise if you want the result for each group that exists in the table then Lukasz Szozda's answer it the way to go.

Related

SQL order groups of data

Here I have a data sample:
Title
Size
Count
First
3
14
First
5
3
Second
2
5
First
2
10
Third
3
10
Second
3
4
Third
2
9
Third
5
11
Second
5
4
Now I want to sort the data with following rules:
Put the records with same title together: First followed by First, Second followed by Second.
Then for each group, order them by size;
For groups, order them in the sum of count of each group, like: sum of First is 14+3+10=27, Second is 5+4+4=13, Third is 10+9+11=30.
The result I want:
Title
Size
Count
Second
2
5
Second
3
4
Second
5
4
First
2
10
First
3
14
First
5
3
Third
2
9
Third
3
10
Third
5
11
It's an easy sort once you get the total "Count" per Title.
A SUM OVER can be used for that.
SELECT
q.title AS "Title"
, q.size AS "Size"
, q.count AS "Count"
FROM
(
SELECT t.title, t.size, t.count
, SUM(t.count) OVER (PARTITION BY t.title) AS TotalCount
FROM yourtable t
) q
ORDER BY q.TotalCount, q.title, q.size
Title
Size
Count
Second
2
5
Second
3
4
Second
5
4
First
2
10
First
3
14
First
5
3
Third
2
9
Third
3
10
Third
5
11
Demo on db<>fiddle here
You can join the results of the group count sums back onto the main table, using the sums in the order by clause:
select t.* from tbl t join
(select t1.title, sum(t1.cnt) s from tbl t1 group by t1.title) t2
on t.title = t2.title order by t2.s, t.title, t.size;
Another approach is by using WITH Queries (Common Table Expressions)
with ct
as (
select title
,size
,count
,sum(count) over (partition by title) sm
from tbl
)
select title
,size
,count
from ct
order by ct.sm,2;

SQL compares the value of 2 columns and select the column with max value row-by-row

I have table something like:
GROUP
NAME
Value_1
Value_2
1
ABC
0
0
1
DEF
4
4
50
XYZ
6
6
50
QWE
6
7
100
XYZ
26
2
100
QWE
26
2
What I would like to do is to groupby group and select the name with highest value_1. If their value_1 are the same, compare and select the max with value_2. If they're still the same, select the first one.
The output will be something like:
GROUP
NAME
Value_1
Value_2
1
DEF
4
4
50
QWE
6
7
100
XYZ
26
2
The challenge for me here is I don't know how many categories in NAME so a simple case when is not working. Thanks for help
You can use window functions to solve the bulk of your problem:
select t.*
from (select t.*,
row_number() over (partition by group order by value1 desc, value2 desc) as seqnum
from t
) t
where seqnum = 1;
The one caveat is the condition:
If they're still the same, select the first one.
SQL tables represent unordered (multi-) sets. There is no "first" one unless a column specifies the ordering. The best you can do is choose an arbitrary value when all the other values are the same.
That said, you might have another column that has an ordering. If so, add that as a third key to the order by.

How to select from SQL table so even and odd rows would be in separate columns?

There is a table ID in my PostgreSQL database.
select * from ID;
ID
1
2
3
4
5
6
7
8
I need to write a query that will give me this output:
id id
1 2
3 4
5 6
7 8
There are no such things as even and odd rows. SQL tables represent unordered sets (well technically multi-sets).
Assuming id is the ordering, you can split them using aggregation like this:
select min(id), max(id)
from (select t.*, row_number() over (order by id) - 1 as seqnum
from t
) t
group by floor(seqnum / 2)

Get offset of a row after performing sort operation in sql

I am using SQLite database.
Suppose I have rows with IDs 1 to 50. Then I perform select and order by operation.
Say, the result is IDs : 6,3,5,2,9,12,1,34,45,15.
Now, I want to know the offset of a particular row with given ID in the above result.e.g. offset of ID 1 is 6.
Can I do this in a single query?
put the query of ordered result into a subquery and use count(*) and check the id sequence:
Example:
SCHEMA:
CREATE TABLE tbl ("id" INTEGER,"val" INTEGER);
INSERT INTO tbl ("id","val")
VALUES
(12,6),(1,7),(34,8),(6,1),(9,5),
(45,9),(15,10),(3,2),(5,3),(2,4);
QUERY:
select id,(
select count(*)
from (
select id,val
from tbl order by val
) b
where a.val >= b.val)-1 as offset
from tbl a
order by offset
RESULT:
id offset
6 0
3 1
5 2
2 3
9 4
12 5
1 6
34 7
45 8
15 9
SQLFIDDLE DEMO

SQL - Order by amount of occurrences

It's my first question here so I hope I can explain it well enough,
I want to order my data by amount of occurrences in the table.
My table is like this:
id Daynr
1 2
1 4
2 4
2 5
2 6
3 1
4 2
4 5
And I want it to sort it like this:
id Daynr
3 1
1 2
1 4
4 2
4 5
2 4
2 5
2 6
Player #3 has one day in the table, and Player #1 has 2.
My table is named "dayid"
Both id and Daynr are foreign keys, together making it a primary key
I hope this explains my problem enough, Please ask for more information it's my first time here.
Thanks in advance
You can do this by counting the number of times that things occur for each id. Most databases support window functions, so you can do this as:
select id, daynr
from (select t.*, count(*) over (partition by id) as cnt
from table t
) t
order by cnt, id;
You can also express this as a join:
select t.id, t.daynr
from table as t inner join
(select id, count(*) as cnt
from table
group by id
) as tg
on t.id = tg.id
order by tg.cnt, id;
Note that both of these include the id in the order by. That way, if two ids have the same count, all rows for the id will appear together.