SQL - внутреннее соединение (где и нет) - PullRequest
0 голосов
/ 17 марта 2020

У меня есть 2 таблицы:

1) STUDENTS-> primery key- id (int)
                     - firstName
                     - lastName
                     - city
2) GRADES->   primery key- studentID (int)
              primery key- courseID ('e' or 'h' or 'm')
                     - grade

Я пытаюсь выбрать имена учеников, которые взяли курс «m» и не взяли курс «h» или «e».

my Решение:

SELECT  * FROM STUDENTS S
INNER JOIN GRADES G1 ON S.ID=G1.STUDENTID
INNER JOIN GRADES G2 ON G1.COURSEID !=G2.COURSEID AND G1.STUDENTID = G1.STUDENTID
WHERE (G1.COURSEID = 'Math ' AND NOT  (G2.COURSEID = 'Eng  ' OR G2.COURSEID = 'Heb'))

Есть идеи, что не так?

Ответы [ 5 ]

0 голосов
/ 17 марта 2020

Вы можете сделать агрегацию:

select s.id
from student s inner join
     grades g
     on g.studentid = s.studentid
group by s.id
having sum(case when g.courseid in ('eng', 'hub') then 1 else 0 end) = 0 and
       sum(case when g.courseid = 'Math' then 1 else 0 end) = 1;
0 голосов
/ 17 марта 2020

Есть несколько способов сделать это.

Вы можете использовать NOT EXISTS или GROUP BY ... HAVING следующим образом:

-- 1

SELECT * FROM STUDENTS S
INNER JOIN GRADES G1 ON S.ID = G1.STUDENTID
WHERE G1.COURSEID = 'Math'
    AND NOT EXISTS (
        SELECT 1 FROM GRADES G2
        WHERE G2.STUDENTID = G1.STUDENTID
          AND G2.COURSEID IN ('Eng','Heb')
    );

-- 2 

SELECT S.ID, S.FIRSTNAME, S.LASTNAME FROM STUDENTS S
       INNER JOIN GRADES G1 ON S.ID = G1.STUDENTID
       WHERE COURSEID IN ('Math','Eng','Heb')
GROUP BY S.ID, S.FIRSTNAME, S.LASTNAME
HAVING SUM(CASE WHEN COURSEID IN ('Eng','Heb') THEN 1 END) = 0
   AND SUM(CASE WHEN COURSEID = 'Math' THEN 1 END) <> 0

Приветствия !!

0 голосов
/ 17 марта 2020

Другой подход с использованием левого соединения

SELECT G1.STUDENTID, G1.firstName, G1.COURSEID!
FROM GRADES G1
LEFT JOIN STUDENTS S ON S.ID=G1.STUDENTID
GROUP BY G1.STUDENTID
HAVING G1.COURSEID='Math' AND G1.COURSEID!='Heb' AND G1.COURSEID!='Eng'

Кроме того, вы должны сохранить в качестве внешнего ключа значение StudentId для таблицы GRADES

0 голосов
/ 17 марта 2020

SELECT a.firstName, a.lastName, b.courseID
FROM STUDENTS a
INNER JOIN GRADES b
ON a.id = b.studentID
AND b.courseID = 'Math'
WHERE a.id NOT IN (
SELECT studentID FROM GRADES b 
WHERE courseID = 'Eng'
OR b.courseID = 'heb')

используйте это

0 голосов
/ 17 марта 2020
SELECT * 
FROM STUDENTS S 
INNER JOIN GRADES G ON S.ID=G.STUDENTID and G.COURSEID = 'Math '
where s.id not in (
  select STUDENTID from GRADES where COURSEID = 'Eng ' OR G2.COURSEID = 'Heb'
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...