Find Maximum across columns in SQL - sql

I have a table with 4 columns SID, Physics, Chemistry, Math. I need to get SID and maximum marks irrespective of the Subject, can anyone help me please.
For Eg
SID Physics Chemistry Maths
1 25 30 85
2 45 28 91
3 97 40 76
Output
SID Max_Marks
3 97

Most databases support least() and greatest(). So, you can do something like this:
select sid, greatest(Physics, Chemistry, Maths) as max_marks
from t
order by max_marks desc
limit 1;
This syntax is more suitable for MySQL. However, you can do something similar in almost any database.

Related

distinct on with case when

I need your help with conditional "distinct on".
For example I have a table "users".
id
name
age
1
John
17
2
Sam
18
3
John
12
4
Sam
19
And I want to do something like:
select case when (u.age > 17) then (distinct on u.name u.*) else (u.*) from users u order by u.name
And I want to do "distinct on" BUT with exclusion, if age is less than 17, then display them as well, if age is greater then take random one.
The output I want is:
id
name
age
1
John
17
2
Sam
18
3
John
12
There are two users with name Sam, and both have age > 17, then I want to apply distinct on in this case.
But there's at least 1 John with age less than 17, therefore I want to have all users with name John in the output.
It might be possible to put this in a condition, but in my opinion, that leads to bad readability.
I would prefer to use UNION ALL here to clearly split these two parts of your query:
SELECT DISTINCT ON (name) id, name, age
FROM users
WHERE age > 17
UNION ALL
SELECT id, name, age
FROM users
WHERE age <= 17
ORDER BY id;
And yes, I know this will select twice from the table, but I think this better in this case unless you observe a very poor performance using this query.

Transpose of Query Result

We have a requirement where we need to transpose the query results .The query result is something like below.
Accnt Country Weight
Acct1 US 55
Acct1 GB 45
Acct2 GB 35
Acct2 US 65
The output need to be transposed like below.
Acct1 Acct2
US 55 65
GB 45 35
I have tied declare block ,but this query will be used in Dot net framework where they cant use declare block.So request the experts let me know possible ways to do this in single query ,both initial and the transpose.The accounts will be dynamic .
You can use PIVOT
select *
from (select Accnt,country,weight from test)
pivot (max(weight) for Accnt IN ('Acct1','Acct2'));
COUNTRY 'Acct1' 'Acct2'
US 55 65
GB 45 35
PIVOT is what you need, but there's also another option.
select Country,
max(case when Accnt = 'Acct1' then Weight end) Acct1,
max(case when Accnt = 'Acct2' then Weight end) Acct2
from test
group by Country;

How to select students who got above average?

How to list all students who got above average grade of their group in SQL table? We have 6 group_ids so there six different average grades.
group_id student grade
1 James 85
1 Adam 96
2 Tom 56
2 Jane 89
2 Anny 90
Result:
group_id student grade
1 Adam 96
2 Jane 89
2 Anny 90
ashkufaraz's answer is closer but not quite right
select group_id,student,grade from students one where grade >
(select avg(grade) from students two where two.group_id = one.group_id)
The question is just tagged SQL, so this is an answer using standard SQL:
One option is to use a window function:
select group_id,student,grade
from (
select group_id,student,grade,
avg(grade) over (partition by group_id) as group_avg
from studends
) t
where grade > group_avg;
This has the additional benefit that you can also display the group average along with the result with no additional join or sub-select.

select same data from two columns in a table, and using one sql statement to show all data

i'm a fresh man in sql area, and i have some question.
the table like below
Table Name:EM
ID name Birth High
1 Tom 11/23 65
2 Mary 11/23 65
3 Bill 03/02 55
4 Liny 01/08 45
5 Kevin 05/16 50
6 Lee 05/16 50
but I only need data like below
ID name Birth High
1 Tom 11/23 65
2 Mary 11/23 65
3 Kevin 05/16 50
4 Lee 05/16 50
and I used fool sql to get data like this
select * from em where birth = '11/23' and high = '65';
select * from em where birth = '05/16' and high = '50';
please teach me how to get result in one sql statement, thank you very much.
you want IN
select * from em where (birth, high) in (('11/23','65'),('05/16','50'));
use OR to combine them:
select * from em where (birth = '11/23' and high = '65') or (birth = '05/16' and high = '50');
You may start learning SQL from here
Use IN and BETWEEN for this check tutorial for IN here and check tutorial for BETWEEN here
This could be your query
SELECT * FROM YOUR_TABLE WHERE COL1 IN (DATE_HERE,ID_HERE) AND/OR COL2 IN (DATE_HERE,ID_HERE)
IN operator is used for adding multiples values
select * from em where birth in ('11/23','05/16') and high in ('65','50');
You can use "or","in" operator
like this:
select * from em
where
birth = '11/23' or birth = '05/16'
and high = '65' or high = '50';

How to get Result from database by order the condition put in "IN" clause?

Sorry for bad english.
bfproduct is a table and productid is primary key in this table and productname is another field defined in this table.
When i execute this query, select * from bfproduct where productid in (23,5,54,3132,32). The result is as follows:
productid | productname
5 15 Park Avenue
23 Good Boy Bad Boy
32 dsf sf gfdsf dsf d
54 dsdsfsa ffs ff sfsf
3132 Just Books - On The Failure of Legal System
Is there any way i will get the resultset in the order by the productid provided in "IN" Clause e.g.
productid | productname
23 Good Boy Bad Boy
5 15 Park Avenue
54 dsdsfsa ffs ff sfsf
3132 Just Books - On The Failure of Legal System
32 dsf sf gfdsf dsf d
Please help...
Here's one way to do it:
SELECT *
FROM bfproduct
WHERE productid
IN (23,5,54,3132,32)
ORDER BY
CASE productid
WHEN 23 THEN 0
WHEN 5 THEN 1
WHEN 54 THEN 2
WHEN 3132 THEN 3
WHEN 32 THEN 4
END
First thing I can think of, try something like...
select bfproduct.*
from bfproduct INNER JOIN
(
select 1 as sequence, 23 as productid
union
select 2,5
union
select 3,54
union
select 4,3132
union
select 5,32
) as lookup on bfproduct.productid=lookup.productid
order by lookup.sequence
(I haven't tested this so there maybe some minor syntax errors!)
You have to add a ORDER BY clause that puts the rows to correct order.