何时使用LEFT JOIN以及何时使用INNER JOIN?

cer*_*erd 34 mysql join

我觉得我总是被教导使用LEFT JOINs而且我经常看到它们与INNERs 混合在一起完成相同类型的查询,这些代码应该在不同的页面上做同样的事情.开始:

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
Run Code Online (Sandbox Code Playgroud)

那就是我正在研究的一个:

我看到很多像:

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
Run Code Online (Sandbox Code Playgroud)

这似乎是LEFT可能也是INNER是否有任何捕获?

Mat*_*ick 106

有没有捕获?是的 - 左连接是外连接的一种形式,而内连接是一种形式的内连接.

以下是显示差异的示例.我们将从基础数据开始:

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 |
+----+-----------+
Run Code Online (Sandbox Code Playgroud)

在这里,我们将看到内连接和左连接之间的区别:

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 |
+----+-----------+----+-----------+
Run Code Online (Sandbox Code Playgroud)

嗯,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      |
+----+------------+------+-----------+
Run Code Online (Sandbox Code Playgroud)

哇,5行!发生了什么?

外连接(例如left join保留不匹配的行) - 因此左连接查询将保留id为2和5的行.其余列用NULL填充.

换句话说,左连接和内连接不可互换.

  • "左连接等外连接保留不匹配的行"此注释ALONE需要在每所学校的每个数据库课程中使用. (10认同)

rob*_*rob 12

这是一个粗略的答案,这就是我对连接的看法.由于上述数学问题,希望这比非常精确的答案更有帮助... ;-)

内连接缩小了行返回的集合.外部联接(左侧或右侧)不会更改返回的行数,但如果可能,只需"拾取"其他列.

在第一个示例中,结果将是AECounts1_low_level_term表中指定的条件匹配的行.然后对于那些行,它尝试加入到1_pref_term1_soc_term.但是如果没有匹配,则行保持不变,并且连接的列为空.


小智 5

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

如您所见,LEFT JOIN包含TableA中ID = 1的行,即使TableB中没有匹配的行ID = 1,而INNER JOIN特别排除了行,因为TableB中没有匹配的行

HTH


小智 5

当您只需要出现在两个表中且与联接条件匹配的结果时,请使用内部联接。

当您需要表 A 中的所有结果,但如果表 B 具有与表 A 的某些记录相关的数据,那么您还想在同一查询中使用该数据时,请使用左联接。

当您需要两个表的所有结果时,请使用完全联接。