#mysql #sql #join
#mysql #sql #Присоединиться
Вопрос:
У меня есть 2 таблицы, контракты и продавцы. Недавно я обнаружил некоторые ошибки в данных, в некоторых контрактах salesid не найден в «продавцах», я подозреваю случайное удаление или какую-то ошибку ввода.
Какое соединение я должен использовать, чтобы найти все контракты, которые не «принадлежат» продавцу, другими словами, contract.salesid не найден в salesmen.id колонна.
Это должно быть правильное внешнее соединение, но результаты получаются неправильными.
Комментарии:
1. Пожалуйста, опубликуйте структуру таблицы
Ответ №1:
Похоже, вы ищете «антисоединение». Объясните расширенные обсуждения о трех способах сделать это в MySQL:
- Левое соединение с
WHERE __ IS NULL
NOT IN
Предложение с подвыбором.NOT EXISTS
Предложение с подвыбором.
Комментарии:
1. 1: для расширенной ссылки explainext, но не забывайте об этом, о том, когда столбцы обнуляются
2. 1 для антисоединения (он же полуразличие) @OMGPonies: похоже, статья о нулевой семантике, относящейся к функции, длиннее, чем статья о самой функции! Хорошая реклама для кампании «избегайте нулей» 🙂
Ответ №2:
Если вы ищете contract.salesid
не найдено в salesmen.id
, вы можете использовать NOT IN()
вместо объединения.
SELECT * FROM contracts WHERE salesid NOT IN (SELECT id FROM salesmen);
Приведенное выше вернет все, contracts
salesid
что не соответствует существующему salesmen.id
. Работа NOT IN ()
с большими таблицами может быть медленнее, чем с помощью a JOIN
, но если ваши таблицы не слишком большие, обычно это более простой метод (на мой взгляд).
Комментарии:
1. Майкл, ваше предложение работает отлично. Однако я приму ответ от 0xCAFEBABE как правильный, поскольку меня в основном интересовал синтаксис соединения. Спасибо за ваше время.
2. @bikey77: Смотрите Ответ ladenedge о том, почему синтаксис соединения не всегда является лучшим выбором.
Ответ №3:
SELECT c.contract_id FROM contract c
LEFT OUTER JOIN salesmen s ON s.salesman_id = c.salesman_id
WHERE c.salesman_id IS NULL
я бы предположил.
Ответ №4:
left outer join
если вы присоединяетесь от контрактов к продавцу
редактировать: неправильный порядок
Комментарии:
1. итак, ‘выберите * из контрактов c, оставив внешнее соединение с продавцами на c.salesid = s.id — сработает? Я пробовал, но я получаю всю таблицу в результатах.
2. ах, извините, я неправильно понял вопрос. я предположил, что вы хотите получить продавцов для контракта, если они существуют. если вы хотите найти пропавших продавцов, проще всего использовать not exists в предложении where
Ответ №5:
Внешнее соединение действительно может это сделать, но почему бы просто не:
select *
from contract c
where c.salesid not in (select s.id
from salesmen s)
Ответ №6:
Я полагаю, это ответ :
select * from Contract c
right outer join Salesmen s on (c.salesid = s.id)
Комментарии:
1. Это даст вам список всех контрактов; столбцы продавцов будут нулевыми, если нет соответствия критериям.
2. Вы прочитали вопрос? «Какое соединение я должен использовать, чтобы найти все контракты, которые не «принадлежат» продавцу»
3. Вы не понимаете — ВСЕ записи, пользователь должен обращать внимание на нули, чтобы знать, что не принадлежит. Большинству просто нужны записи, которые не принадлежат 😉