Какой тип соединения мне нужен?

#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. Вы не понимаете — ВСЕ записи, пользователь должен обращать внимание на нули, чтобы знать, что не принадлежит. Большинству просто нужны записи, которые не принадлежат 😉