2012-03-21 5 views
16

Я чувствую, что меня всегда учили использовать LEFT JOIN s, и я часто вижу их смешанными с INNER s, чтобы выполнить тот же тип запроса на нескольких фрагментах кода, которые должны делать то же самое на разных страницах. Здесь идет:Когда использовать LEFT JOIN и когда использовать INNER JOIN?

SELECT ac.reac, pt.pt_name, soc.soc_name, pt.pt_soc_code 
FROM 
    AECounts ac 
    INNER JOIN 1_low_level_term llt on ac.reac = llt.llt_name 
    LEFT JOIN 1_pref_term pt ON llt.pt_code = pt.pt_code 
    LEFT JOIN 1_soc_term soc ON pt.pt_soc_code = soc.soc_code 
LIMIT 100,10000 

Вот один я работаю:

Я вижу много, как:

SELECT COUNT(DISTINCT p.`case`) as count 
FROM FDA_CaseReports cr 
    INNER JOIN ae_indi i ON i.isr = cr.isr 
    LEFT JOIN ae_case_profile p ON cr.isr = p.isr 

Это похоже СЛЕВА, а может быть ВНУТРЕННИЙ есть ли подвох?

+0

Спасибо за очищение кода michael, только что вернулся к этому, +1 – cerd

ответ

60

Есть ли улов? Да есть - левые соединения - это форма внешнего соединения, а внутренние соединения - это форма, ну, внутреннее соединение.

Вот примеры, которые показывают разницу. Мы начнем с базой данных:

mysql> select * from j1; 
+----+------------+ 
| id | thing  | 
+----+------------+ 
| 1 | hi   | 
| 2 | hello  | 
| 3 | guten tag | 
| 4 | ciao  | 
| 5 | buongiorno | 
+----+------------+ 

mysql> select * from j2; 
+----+-----------+ 
| id | thing  | 
+----+-----------+ 
| 1 | bye  | 
| 3 | tschau | 
| 4 | au revoir | 
| 6 | so long | 
| 7 | tschuessi | 
+----+-----------+ 

И здесь мы видим разницу между внутренним соединением и левым соединением:

mysql> select * from j1 inner join j2 on j1.id = j2.id; 
+----+-----------+----+-----------+ 
| id | thing  | id | thing  | 
+----+-----------+----+-----------+ 
| 1 | hi  | 1 | bye  | 
| 3 | guten tag | 3 | tschau | 
| 4 | ciao  | 4 | au revoir | 
+----+-----------+----+-----------+ 

Хм, 3 строками.

mysql> select * from j1 left join j2 on j1.id = j2.id; 
+----+------------+------+-----------+ 
| id | thing  | id | thing  | 
+----+------------+------+-----------+ 
| 1 | hi   | 1 | bye  | 
| 2 | hello  | NULL | NULL  | 
| 3 | guten tag | 3 | tschau | 
| 4 | ciao  | 4 | au revoir | 
| 5 | buongiorno | NULL | NULL  | 
+----+------------+------+-----------+ 

Wow, 5 rows! Что случилось?

Внешние соединения, такие как left join, сохраняют строки, которые не совпадают, поэтому строки с идентификаторами 2 и 5 сохраняются в левом запросе соединения. Остальные столбцы заполняются NULL.

Другими словами, левое и внутреннее соединения не являются взаимозаменяемыми.

+0

Привет, спасибо, это отличное объяснение для новичка. – user1149244

+0

nice, thanks @ matt-fenwick – minhajul

+6

«Внешние соединения, такие как левое соединение, сохраняют строки, которые не совпадают» Этот комментарий ALONE должен использоваться в каждом курсе базы данных в каждой школе. – AbbyPaden

5

внутреннего соединение будет возвращать только те строки, где Есть соответствующие значения в обеих таблицах, в то время как LEFT JOIN возвращает все строки из таблицы ЛЕВОЙ, даже если нет соответствующей строки в таблице справа

A быстрый пример

TableA 
ID Value 
1 TableA.Value1 
2 TableA.Value2 
3 TableA.Value3 

TableB 
ID Value 
2 TableB.ValueB 
3 TableB.ValueC 

внутреннее объединение производит:

SELECT a.ID,a.Value,b.ID,b.Value 
FROM TableA a INNER JOIN TableB b ON b.ID = a.ID 

a.ID a.Value   b.ID b.Value 
2  TableA.Value2  2  TableB.ValueB 
3  TableA.Value3  3  TableB.ValueC 

LEFT JOIN производит:

SELECT a.ID,a.Value,b.ID,b.Value 
FROM TableA a LEFT JOIN TableB b ON b.ID = a.ID 

a.ID a.Value   b.ID b.Value 
1  TableA.Value1  NULL NULL 
2  TableA.Value2  2  TableB.ValueB 
3  TableA.Value3  3  TableB.ValueC 

Как вы можете видеть, LEFT JOIN включает строку из таблицы A, где ID = 1, даже если в таблице B нет идентификационной строки, где ID = 1, тогда как INNER JOIN исключает строку специально, потому что нет соответствующей строки в Таблица B

HTH

7

Вот грубый ответ, вот как я думаю о соединениях. Надеясь, что это будет более полезно, чем очень точный ответ из-за вышеупомянутых математических проблем ... ;-)

Внутренние соединения сужают набор строк. Внешние соединения (слева или справа) не меняют число возвращаемых строк, а просто «подбирают» дополнительные столбцы, если это возможно.

В вашем первом примере результатом будут строки от AECounts, которые соответствуют условиям, указанным в таблице 1_low_level_term. Затем для этих строк, это пытается присоединиться к 1_pref_term и 1_soc_term. Но если совпадения нет, строки остаются, а объединенные в столбцах - нулевые.

+1

хорошее объяснение от нового пользователя, +1 – deltree

+0

+1. Хороший ответ. Добро пожаловать в stackoverflow rob. – Leigh

+0

Большое спасибо. Мог бы добавить, что внешнее соединение может ** добавить ** строки, если присоединяется к не уникальным ключам, но ... – rob

1

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

Используйте левое соединение, если хотите получить все результаты из таблицы A, но если в таблице B есть данные, относящиеся к некоторым записям таблицы А, то вы также захотите использовать эти данные в том же запросе.

Используйте полное соединение, если хотите получить все результаты из обоих таблиц.

+0

вы можете поддержать свой ответ с помощью некоторых фрагментов кода или ссылок? это звучит немного слишком широко. – Farside

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