2014-09-21 5 views
4

У меня есть один стол (скрабы) с 1600 уникальными предметами. Второй стол с 1 миллионом плюс. Я бегу мой INNER JOIN и получить 65 матчей:LEFT JOIN возвращает тот же результат, что и INNER JOIN

SELECT a.`BW Parent Number` , a.`Vendor Name`, b.`Parent Supplier Name` 
FROM `scrubs` AS a 
JOIN pdwspend AS b ON a.`BW Parent Number` = b.`Child Supplier ID` 
WHERE a.`year` =2014 
AND b.`BU ID` = 'BU_1' 
AND b.version LIKE '%GOV%' 
GROUP BY a.`BW Parent Number` 

Тогда я бегу LEFT OUTER JOIN, и я получаю то же самое, 65 результаты:

SELECT a.`BW Parent Number` , a.`Vendor Name`, b.`Parent Supplier Name` 
FROM `scrubs` AS a 
LEFT OUTER JOIN pdwspend AS b ON a.`BW Parent Number` = b.`Child Supplier ID` 
WHERE a.`year` =2014 
AND b.`BU ID` = 'BU_1' 
AND b.version LIKE '%GOV%' 
GROUP BY a.`BW Parent Number` 

Почему не доводя все строки слева таблицу и показывая NULL для тех, которые не совпадают под b. Parent Supplier Name?

Спасибо!

ответ

9

Потому что вы не используете предложение on. Измените его на:

SELECT a.`BW Parent Number`, a.`Vendor Name`, b.`Parent Supplier Name` 
    FROM scrubs AS a 
    LEFT OUTER JOIN pdwspend AS b 
    ON a.`BW Parent Number` = b.`Child Supplier ID` 
    and b.`BU ID` = 'BU_1' 
    AND b.`version` LIKE '%GOV%' 
WHERE a.`year` = 2014 

Также группа не имеет никакого смысла. Вы бы использовали предложение group by, если вы что-то агрегируете.

Основываясь на вашем комментарии к повторяющимся строкам, это, вероятно, потому, что таблица «pdwspend» имеет более одной строки для каждого «идентификатора поставщика детства». И это единственное поле на той таблице, с которой вы присоединяетесь к таблице «scrubs». Так что да, для каждой соответствующей строки на pdwspend у вас будет столько строк, сколько есть на этой второй таблице (в этой таблице есть другие столбцы, поэтому они действительно не «повторяющиеся» строки, вы просто не выбираете достаточно столбцов для иллюстрации).

Поскольку вы заинтересованы только в определенном количестве столбцов и не хотите строки «повторяются» на основе этих столбцов можно попробовать отчетливыми с помощью:

(причины вы получите сообщение об ошибке в запросе вы положили в ваших комментариях, потому что ваш встроенный просмотр - подзапрос в вашем предложении from - не выбирает поле «родительское имя поставщика», поэтому да, он не существует в этом встроенном представлении, потому что вы не добавили его в выбранный список этого инлайн зрения.

 select a.`BW Parent Number`, a.`Vendor Name`, b.`Parent Supplier Name` 
     from scrubs a 
    left join (select distinct `Child Supplier ID`, `Parent Supplier Name` 
         from pdwspend 
         where `BU ID` = 'BU_1' 
          and `version` LIKE '%GOV') b 
     on a.`BW Parent Number` = b.`Child Supplier ID` 
     where a.`year` = 2014 
+0

Что происходит, что каждый b.'Child Поставщик ID' из таблицы pdwspend могут отображаться сотни раз. Когда я присоединяюсь без него, он приносит каждое совпадение, поэтому у меня много повторяющихся строк. Я думаю, что лучшее решение может быть в этом отношении ... это также приводит к ошибке !: – nangys

+0

SELECT a.'BW Parent Number', a.'Vendor Name', b.'Родитель Поставщик name' ОТ скрабы AS в LEFT OUTER JOIN ( SELECT DISTINCT' ребенка поставщика ID' ОТ pdwspend ГДЕ 'year' = 2014 И' БУ ID' = '' BU_1 И версия LIKE «% GOV% ') AS b ON a.'BW Родительский номер' = b.'Child ID поставщика ГДЕ a.'year' = 2014 # 1054 - Неизвестная колонка' b.Parent Supplier Name 'in' field list ' – nangys

+0

Вы не включили 'b.Parent Supplier Name' внутри' select select subquery'. Пересмотрите запрос Брайана и скопируйте его –

7

Почему не доводя все строки из левой таблицы и показывать NULL для го e, которые не совпадают?

Причина, по которой ваш LEFT JOIN не работал должным образом из-за условий на этой таблице в пункте WHERE; это иногда называют «неявное внутреннее соединение».

Это лучше всего объясняется демонстрацией. Ниже приведены 2 простых таблиц

| USER_ID | FIRST_NAME | LAST_NAME | 
    |---------|------------|------------| 
    |  123 |  Fred | Flintstone | 
    |  456 |  Barney |  Rubble | 

    | ID | USER_ID |  NOTE_BODY | 
    |-------|---------|-----------------| 
    | 98765 |  123 | Yabba Dabba Doo | 

Так как и следовало ожидать, внутреннее объединение производит только один ряд, где User_ID значения совпадают в обеих таблицах.

SELECT * FROM пользователей у INNER JOIN user_notes п ON u.User_ID = п.Идентификатор пользователя;

| USER_ID | FIRST_NAME | LAST_NAME | ID |  NOTE_BODY | 
    |---------|------------|------------|-------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 

И изменения в LEFT JOIN мы получаем все записи пользователей, но не все имеют информацию от User_Notes, так что мы получаем NULLs в этих колонках

SELECT * FROM пользователей у LEFT JOIN user_notes n ON u.User_ID = n.User_ID;

| USER_ID | FIRST_NAME | LAST_NAME |  ID |  NOTE_BODY | 
    |---------|------------|------------|--------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 
    |  456 |  Barney |  Rubble | (null) |   (null) | 

Но что произойдет, если мы действительно только хотите несколько записей из присоединяемой таблицы?

SELECT * FROM пользователей у LEFT JOIN user_notes п = О u.User_ID n.User_ID ГДЕ n.Note_Body = 'Yabba Dabba Ду';

| USER_ID | FIRST_NAME | LAST_NAME | ID |  NOTE_BODY | 
    |---------|------------|------------|-------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 

Ну, если мы используем условие WHERE, эффект такой же, как присоединиться к ВНУТРЕННЕЙ, теперь мы не получаем все записи пользователя и это неявный внутреннее соединение.

Причина, по которой мы не получаем все записи пользователя, состоит в том, что мы теперь настаивали на том, чтобы все строки результатов ДОЛЖНЫ иметь определенное значение в столбце, который может быть NULL. Таким образом, мы могли бы изменить условие WHERE, чтобы разрешить NULL.

SELECT * FROM пользователей у LEFT JOIN user_notes п = О u.User_ID n.User_ID ГДЕ (n.Note_Body = 'Yabba Dabba Doo' ИЛИ n.Note_Body IS NULL);

| USER_ID | FIRST_NAME | LAST_NAME |  ID |  NOTE_BODY | 
    |---------|------------|------------|--------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 
    |  456 |  Barney |  Rubble | (null) |   (null) | 

ИЛИ

Вместо того, чтобы использовать ИНЕКЕ на присоединяемой таблицы мы добавим к условиям Join (ieafter ON)

SELECT * FROM пользователей у LEFT JOIN user_notes n ON u.User_ID = n.User_ID И n.Note_Body = 'Yabba Dabba Д ';

| USER_ID | FIRST_NAME | LAST_NAME |  ID |  NOTE_BODY | 
    |---------|------------|------------|--------|-----------------| 
    |  123 |  Fred | Flintstone | 98765 | Yabba Dabba Doo | 
    |  456 |  Barney |  Rubble | (null) |   (null) | 

Итак, будьте осторожны при использовании внешних соединений, что ваш где положение не отменяют NULLs, что внешнее соединение позволяет.

See the above as a SQLFiddle demonstration

+0

Спасибо за ответ! Было очень полезно – nangys

+0

никаких проблем, upvote также показывает оценку (подсказка) –

+0

@robsch nice edit, thanks. –

Смежные вопросы