Когда использовать LEFT JOIN и когда использовать INNER JOIN?

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

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

Кажется, что LEFT также может быть INNER, есть ли улов?

Ответы

Ответ 1

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

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

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      |
+----+------------+------+-----------+

Ничего себе, 5 строк! Что случилось?

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

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

Ответ 2

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

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

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

Ответ 3

INNER JOIN будет возвращать только строки, в которых есть соответствующие значения в обеих таблицах, тогда как LEFT JOIN вернет ВСЕ строки из таблицы LEFT, даже если в таблице RIGHT нет соответствующей строки

Быстрый пример

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

TableB
ID   Value
2    TableB.ValueB
3    TableB.ValueC

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

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

НТН

Ответ 4

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

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

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

Ответ 5

Для новичков, потому что это помогло мне, когда я был один: INNER JOIN всегда является подмножеством LEFT или RIGHT JOIN, и все они всегда являются подмножествами FULL JOIN. Это помогло мне понять основную идею.