Home > Blockchain >  SQL- Find all students who all of their friends have score less than 10
SQL- Find all students who all of their friends have score less than 10

Time:05-06

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.

CodePudding user response:

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;

CodePudding user response:

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
);
  • Related