'SQL- Find all students who all of their friends have score less than 10
I have to write some simple queries for my database homework using SQLServer. The schema has been provided in the question:
students(student_id, name);
friends(student_id, friend_id);
db_grades(student_id, grade);
For every pair of friends, 2 rows like (x, y) and (y, x) would be added to the friends table
Find all students, who all of their friends have a score of less than 10
First I tried to solve this question using GROUP BY, and I wrote the below query.
Select Distinct s.name, MAX(g.grade)
From (students s inner join friends f on s.student_id = f.student_id), db_grades g
Where f.friend_id = g.student_id
Group by f.friend_id, s.name
Having MAX(g.grade) < 10;
And in the second try, I wanted to implement it using the IN keyword, but it also does not work correctly.
Select distinct s.name
From students s join friends f on s.student_id = f.student_id
Where f.friend_id not in
(
Select f.friend_id
From db_grades g1
Where g1.student_id = f.friend_id and g1.grade > 10
)
I will be grateful for your help on how to write the correct query.
Solution 1:[1]
Aggregation is one option:
SELECT s.student_id, s.name
FROM students s
INNER JOIN friends f
ON f.student_id = s.student_id
INNER JOIN db_grades g
ON g.student_id = f.friend_id
GROUP BY s.student_id, s.name
HAVING COUNT(CASE WHEN f.grade >= 10 THEN 1 END) = 0;
Solution 2:[2]
Another option is to use NOT EXISTS. Note that the difference between this and HAVING with an INNER JOIN is that this option includes those that have no friends at all.
SELECT s.student_id, s.name
FROM students s
WHERE NOT EXISTS (SELECT 1
FROM friends f
INNER JOIN db_grades g
ON g.student_id = f.friend_id
WHERE f.student_id = s.student_id
AND g.grade >= 10
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Tim Biegeleisen |
| Solution 2 | Charlieface |
