#sql #join
#sql #Присоединиться
Вопрос:
Я пытаюсь получить данные из одной таблицы, поэтому я присоединяюсь к ней следующим образом:
SELECT A.ACCT_NO
FROM ACCOUNT AS A
RIGHT OUTER JOIN CUSTOMER AS C
ON A.CUST_ID = C.CUST_ID
WHERE C.FIRST_NM = 'ADAM';
Проблема сейчас в том, что я несколько смущен тем, как функционируют соединения. Если я изменю его на:
LEFT OUTER JOIN CUSTOMER AS C
Или даже:
INNER JOIN CUSTOMER AS C
Я получаю те же точные данные! Я следую этой диаграмме прямо здесь:
http://i.stack.imgur.com/1UKp7.png
Исходя из этого, я предположил, что будет работать только ПРАВИЛЬНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ, потому что оно только извлекает столбцы из CUSTOMER. Однако, похоже, это не так, поскольку работают оба внешних соединения. Кроме того, я был потрясен, увидев, что внутреннее соединение также работает. Почему это? Или это потому, что мне не хватает ключевых понятий в отношении join в SQL?
Спасибо!
Комментарии:
1. Вы, похоже, были очень смущены тем, как работают объединения. en.wikipedia.org/wiki/Join_ (SQL)
2. При использовании внешних соединений в объединении ДОЛЖНЫ быть указаны ограничивающие критерии для таблицы, в которой вам нужны только совпадающие записи, или вы должны использовать условие или для обработки NULL
3. Вы сказали: «Или это потому, что я упускаю ключевые понятия, касающиеся join в SQL? » Да, этот момент. Вам не хватает ключевой концепции, касающейся того, когда к результирующему набору применяются ограничивающие критерии, по сравнению с тем, когда генерируется декартова форма объединения.
Ответ №1:
Этот запрос вернет значения null для значений, которых нет в таблице Account, и всех записей из таблицы Customer
SELECT *
FROM ACCOUNT AS A
RIGHT OUTER JOIN CUSTOMER AS C
ON A.CUST_ID = C.CUST_ID
Этот запрос вернет значения null для значений, которых нет в таблице Customer, и всех записей из таблицы Account
SELECT *
FROM ACCOUNT AS A
LEFT JOIN CUSTOMER AS C
ON A.CUST_ID = C.CUST_ID
Этот запрос не вернет строки, которые не имеют эквивалентов в таблице customer, поэтому только строки из учетных записей, у которых есть клиенты.
SELECT *
FROM ACCOUNT AS A
INNER JOIN CUSTOMER AS C
ON A.CUST_ID = C.CUST_ID
Комментарии:
1. и
WHERE C.FIRST_NM = 'ADAM'
превращаетLEFT JOIN CUSTOMER AS C
во внутреннее соединение
Ответ №2:
При использовании внешних соединений в соединении ДОЛЖНЫ быть размещены ограничивающие критерии для таблицы, в которой вам нужны только совпадающие записи, или вы должны использовать условие или для обработки NULL. Если вы этого не сделаете, вы получите те же результаты, что и при ВНУТРЕННЕМ соединении. Это связано с тем, когда происходит объединение, и с тем, когда применяются критерии предложения where. Когда ограничивающий критерий находится в соединении, это происходит перед соединением, в предложении where, после. Когда в предложении where значения NULL, сгенерированные внешним соединением, затем исключаются … предложением where … что делает его похожим на внутреннее соединение.
Поскольку я думаю, что вам нужны все учетные записи, но только информация о клиенте, где имя — Адам, вам нужно левое соединение, но переместите критерии предложения where в соединение.
ПРЕДПОЧТИТЕЛЬНЫЙ:
SELECT A.ACCT_NO
FROM ACCOUNT AS A
LEFT OUTER JOIN CUSTOMER AS C
ON A.CUST_ID = C.CUST_ID
AND C.FIRST_NM = 'ADAM';
или
Если вы должны
SELECT A.ACCT_NO
FROM ACCOUNT AS A
LEFT OUTER JOIN CUSTOMER AS C
ON A.CUST_ID = C.CUST_ID
WHERE (C.FIRST_NM = 'ADAM' OR c.First_NM is null)
но c.First_NM не должен иметь значения null, иначе вы не сможете отличить значение null в соединении от значения null в записи.
http://blog.codinghorror.com/a-visual-explanation-of-sql-joins / за помощью по объединениям.
ПОРЯДОК таблиц имеет значение…
- Если вам нужны все клиенты и только те учетные записи, которые соответствуют клиенту, тогда используйте
RIGHT JOIN
, как вы указали. - Если вам нужны все учетные записи и только те клиенты, у которых есть связанная учетная запись, используйте
LEFT JOIN
- Если вы хотите, чтобы все учетные записи и все клиенты использовали
FULL OUTER JOIN
- Если вам нужны только клиенты с учетными записями, используйте
INNER JOIN
Ответ №3:
Вероятно, это означает, что у вас есть совпадение по каждому ключу.
Если нет несоответствий ключей, все RIGHT JOIN
, LEFT JOIN
и INNER JOIN
должны возвращать одни и те же данные.
Итак, вы видите, что для каждого клиента, названного 'ADAM'
в CUSTOMER
, есть соответствующая запись в ACCOUNT
.