Какой запрос Join для SQL плюс - PullRequest
0 голосов
/ 13 мая 2018

У меня есть 4 таблицы, я хотел бы выбрать один столбец из каждой таблицы, но только если в отделе работают как «Мик», так и «Дейв» (должны быть оба имени, а не одно или другое). Но, похоже, он не работает должным образом:

SELECT SCHOOL_NAME, TOWN, COUNTY
FROM STUDENTS 
NATURAL JOIN SCHOOLS NATURAL JOIN TOWNS NATURAL JOIN 
COUNTIES
WHERE FIRST_NAME IN ('Mick','Dave)
/

Я где-то ошибаюсь (вероятно, много мест :(). Любая помощь будет отличной

Ответы [ 3 ]

0 голосов
/ 13 мая 2018

Не используйте NATURAL JOIN. Это мерзость, потому что она не учитывает должным образом объявленные отношения внешнего ключа. Он смотрит только на названия столбцов. Это может привести к очень трудно найти ошибки.

Второе, что вам нужно, это агрегация:

select sc.SCHOOL_NAME, t.TOWN, c.COUNTY
from STUDENTS st join
     SCHOOLS sc
     on st.? = sc.? join
     TOWNS t 
     on t.? = ? join
     COUNTIES c
     on c.? = t.?
where FIRST_NAME in ('Mick', 'Dave')
group by sc.SCHOOL_NAME, t.TOWN, c.COUNTY
having count(distinct st.first_name) = 2;

? - это заполнители для имен таблиц и столбцов. Если вы изучаете SQL, тем более важно понимать, как выстраиваются столбцы для объединений в разных таблицах.

Предложение where может проверять значения только в одной строке. Для каждого учащегося есть отдельная строка, поэтому просто - where - невозможно найти обоих учеников. Вот где начинается агрегация.

0 голосов
/ 14 мая 2018

Вы можете использовать аналитическую функцию в подзапросе для подсчета учеников, у которых есть имя Mick или Dave для каждого school_id (при условии, что это ваш идентификатор для школы):

SELECT SCHOOL_NAME, TOWN, COUNTY
FROM ( SELECT *
       FROM   (
         SELECT d.*,
                COUNT(
                  DISTINCT
                  CASE WHEN FIRST_NAME IN ( 'Mick', 'Dave' ) THEN FIRST_NAME END
                ) OVER( PARTITION BY school_id )
                  AS num_matched
         FROM   STUDENTS d
       )
       WHERE num_matched = 2
     )
     NATURAL JOIN SCHOOLS
     NATURAL JOIN TOWNS
     NATURAL JOIN COUNTIES;

SQLFiddle

Также было бы лучше использовать INNER JOIN и явно указывать условие соединения, а не полагаться на NATURAL JOIN.

0 голосов
/ 13 мая 2018

Вам нужно как минимум three Join conditions и правильно завершить строку Dave с кавычкой:

SELECT SCHOOL_NAME, TOWN, COUNTY
  FROM SCHOOLS h 
  JOIN TOWNS t ON (t.id=h.town_id) 
  JOIN COUNTIES c ON (t.county_id=c.id) 
 WHERE EXISTS ( SELECT school_id 
                  FROM STUDENTS s
                 WHERE s.first_name in ('Mick','Dave')
                   AND school_id = h.id
                GROUP BY school_id
                HAVING count(1)>1
                  );

Демонстрация SQL Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...