Sort by aggregate value in sql - sql

Let's say I have the following student data:
classroom gender student_id
-------------------------------------
First Grade M 123
First Grade F 124
First Grade F 125
Second Grade M 126
Third Grade M 127
...
I want to produce the following result: top 3 biggest classrooms ordered by total number of students with detail for each:
classroom boys_count girls_count total_count
--------------------------------------------------
Third Grade 30 30 60
First Grade 20 5 25
Fourth Grade 10 10 20
How can I do that in sql ? If necessary, I can use specific postrges features.
What I tried so far:
SELECT count(*) as total_count
, gender
, classroom
ORDER BY 1
GROUP BY classroom, gender
LIMIT 3
Then I re-organise results in some scripting language. But this is too slow. I want to have the correct results with one query

select classroom as name,
sum(case when gender = 'M' then 1 else 0 end) as boys_count,
sum(case when gender = 'F' then 1 else 0 end) as girls_count,
count(*) as total_count
from your_table
group by classroom
order by count(*) desc
limit 3

Related

SQL Group by on multiple conditions on same table

enter image description hereI am trying to write an SQL query to get below output.
table has below data:
ID GENDER
10 M
10 F
10 F
20 F
20 M
Output:
ID Male Female
10 1 2
20 1 1
do i need to use case with group by. Can someone help here.
use simple group
select id,sum(case when GENDER = 'M' then 1 else 0 end) as Male,
sum(case when GENDER = 'F' then 1 else 0 end) as FeMale
from tablename
group by id

sql query with group by to find disposed and pending assignment by student

I have a table called assignment:
assignment_id student_id report_id
--------------------------------------
25 1 0
56 2 10
28 1 5
94 1 0
75 1 0
86 1 0
95 2 5
I'm using this SQL query to find out total number of assignment received by each student
select student_id as student, count(assignment_id) as total_assignment ,
from assignment
group by student_id
order by student_id asc
Result of this query is
student total_assignment
---------------------------
1 5
2 2
In assignment table where report_id == 0, assignment is pending otherwise assignment is disposed. I need to also find total disposed and pending assignment by each student.
Please help me complete this above SQL query. Thanks
Just use conditional aggregation:
select student_id as student, count(*) as total_assignment,
sum(case when report_id = 0 then 1 else 0 end) as num_pending,
sum(case when report_id <> 0 then 1 else 0 end) as num_completed
from assignment
group by student_id
order by student_id asc;
As a matter of word choice: I prefer "completed" to "disposed". At least in American English, "disposed" has the connotation of being thrown out as garbage.

How to find number of failed grades and the number of general average?

I have A table of students and their grades.
How can I count the number of failed grades (<50)
and find the general average ( I mean the average for every student ) using sqlite?
this is the table (studentTable):
sID LessonID grade
1 1 45
1 2 50
1 3 65
2 1 44
2 2 22
2 3 91
I expect the results like this:
sID noOfFails Average
1 1 53
2 2 5
Try
SELECT
sID,
SUM(CASE WHEN grade < 50 THEN 1 ELSE 0 END) AS noOfFails,
AVG(grade) AS Average
FROM studentTable
GROUP BY sID
Demo at http://sqlfiddle.com/#!5/fcd13/1
You could use a case expression inside the count function:
SELECT sID, COUNT(CASE WHEN grade < 50 THEN 1 END) AS noOfFails, AVG(grade)
FROM mytable
You can simply run it as follows:
SELECT sID, COUNT(IIF(grade<50,1,NULL)) as noOfFails, AVG(grade) as Average
FROM studentTable GROUP BY sID

Getting the count of resultset along with result rows

I have a SQL query for which I needed to have result rows count and results as the output of query.
For example,
SELECT count(*) total, id, name, age, grade
FROM Employee
where grade = 10;
It prints only one row with total count.
Please let me know what could be missing in query.
With GROUP BY:
Table:
id name age grade
1 ABC 30 10
2 DEF 31 10
3 GHI 29 6
4 PQR 29 10
Query:
SELECT count(*) total, id, name, age, grade
FROM Employee
where grade = 10
group by id, name, age, grade
total id name age grade
1 1 ABC 30 10
1 2 DEF 31 10
1 4 PQR 29 10
Under total, I expect to have 3 as the value although it will be repeated.
Here my intention is to have total row count and result rows as part of single query.
Perhaps a GROUP BY is what you want?
SELECT count(*) total, id, name, age, grade
FROM Employee
where grade = 10
group by id, name, age, grade
SQLite computes result rows on the fly, so it does not know the size of the result set until you have fetched the last row.
If possible, change your program so that it just can count the rows.
If you really want to have the row count in every row, you have to compute it separately:
SELECT (SELECT COUNT(*)
FROM Employee
WHERE grade = 10
) AS total,
id, name, age, grade
FROM Employee
WHERE grade = 10;
Try this
SELECT * FROM
((SELECT COUNT(*) as total FROM EMPLOYEES
WHERE grade = 10)
CROSS JOIN
(SELECT id, name, age, grade
FROM Employee
where grade = 10))

Count without nested select: is this possible?

Database:
Department Position Points
A Manager 50
A Supervisor 10
A Supervisor 10
A Staff 2
A Staff 2
B Manager 40
B SuperVisor 8
B Staff 2
B Staff 2
B Staff 2
Desired query result:
Dept Manager Count Supervisor Count Staff Count Staff Total Pts
A 1 2 2 4
B 1 1 3 4
Is the desired query result possible without using nested select with count?
We have a certain stored procedure similar to this using nested counts and we like to make it simpler and perform better/faster
Use Conditional Aggregate to count only the specific data
Select Department,
count(case when Position = 'Manager' then 1 END) as Manager,
count(case when Position = 'Supervisor' then 1 END) as Supervisor,
count(case when Position = 'Staff' then 1 END) as Staff
From yourtable
Group by Department
If you are using Sql Server use this
SELECT Department,
Manager,
Supervisor,
Staff
FROM Yourtable
PIVOT (Count(Position)
FOR Position IN (Manager,Supervisor,Staff))pv
Use conditional SUM:
SELECT Department,
SUM(CASE WHEN Position = 'Manager' THEN 1 END) as Manager,
SUM(CASE WHEN Position = 'Supervisor' THEN 1 END) as Supervisor,
SUM(CASE WHEN Position = 'Staff' THEN 1 END) as Staff
FROM yourtable
GROUP BY Department
Or You can use PIVOT operator:
select Detartment, Manager, Supervisor, Staff
from yourtable
pivot (count(Position) for Position in (Manager, Supervisor, Staff)) Result