本文详细解析了在SQL查询语句中使用ON和WHERE来设置过滤条件的不同之处,帮助读者理解何时以及如何正确运用这两个关键字。
在SQL查询中,`ON` 和 `WHERE` 都用于设置过滤条件,但它们在不同类型的查询中扮演的角色和产生的效果是有区别的。本篇文章将深入探讨`ON`和`WHERE`在`JOIN`操作中的具体差异,并通过实例来帮助理解。
`JOIN`操作是SQL中用于合并两个或更多表的数据的关键部分。主要有四种类型的`JOIN`: `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN` 和 `FULL OUTER JOIN`. 我们首先关注 `INNER JOIN`, 因为它是使用`ON`和`WHERE`最相似的情况。
1. **INNER JOIN**:
- 在`INNER JOIN`中,可以同时用到`ON`和`WHERE`来设置过滤条件。但是它们的应用顺序不同。
- 使用 `ON` 设置的条件会在两个表进行笛卡尔积运算之后对结果进行初步筛选,也就是说,在连接操作发生后应用这些条件。
- 如果在执行 `INNER JOIN` 的时候既使用了 `ON`, 也用了 `WHERE`, 那么 `WHERE` 条件会进一步过滤由 `ON` 过滤后的数据集。
- 示例:
```sql
SELECT * FROM person p INNER JOIN account a ON p.id = a.id AND p.id != 4 AND a.id != 4;
SELECT * FROM person p INNER JOIN account a ON p.id = a.id WHERE p.id != 4 AND a.id != 4;
```
这两个查询的结果是相同的,因为在 `INNER JOIN` 中, `ON` 和 `WHERE` 的过滤条件都只对最终的匹配结果生效。
2. **LEFT JOIN**(或`RIGHT JOIN`):
- `LEFT JOIN`(或`RIGHT JOIN`)保留左表(或右表)的所有记录,即使在右表(或左表)中没有匹配的记录。
- 使用 `ON` 设置条件仅对非主侧有效, 而 `WHERE` 则作用于整个结果集。
- 当使用 `LEFT JOIN` 时,如果通过 `ON` 条件未能找到对应的行,则该行在连接的另一端为NULL。
- 示例:
```sql
SELECT * FROM person p LEFT JOIN account a ON p.id = a.id AND p.id != 4 AND a.id != 4;
```
在这个例子中, 即使有 `p.id != 4` 的条件,`LEFT JOIN` 还是会保留所有来自 `person` 表的记录,只是在没有匹配到对应行的情况下,其对应的字段值为NULL。
如果添加了 `WHERE` 条件:
```sql
SELECT * FROM person p LEFT JOIN account a ON p.id = a.id WHERE p.id != 4 AND a.id != 4;
```
这时, `WHERE` 条件会过滤掉在 `person` 表中ID为4的记录,即使在执行了 `LEFT JOIN` 的情况下使用了 `ON`, 因为 `WHERE` 是在整个结果集上进行操作。
总结来说,`ON` 主要用于定义两个表之间的关联条件, 而 `WHERE` 则对整个查询的结果进行过滤。在 `INNER JOIN` 中两者的作用基本相同,在执行 `LEFT JOIN` 和 `RIGHT JOIN` 时,它们的效果会有所不同:使用 `ON`, 过滤仅限于非主侧的记录;而通过 `WHERE`, 可以在整个结果集中应用条件。
理解这些区别对于编写更高效、准确的SQL查询至关重要。希望这篇文章的内容能帮助你理解和运用`ON`和`WHERE`的区别,如有任何疑问欢迎进一步交流讨论。