预备知识
1.内连接
MySQL INNER JOIN子句介绍
MySQL INNER JOIN
子句将一个表中的行与其他表中的行进行匹配,并允许从两个表中查询包含列的行记录。
INNER JOIN
子句是SELECT
语句的可选部分,它出现在FROM
子句之后。
在使用INNER JOIN
子句之前,必须指定以下条件:
首先,在FROM
子句中指定主表。其次,表中要连接的主表应该出现在INNER JOIN
子句中。理论上说,可以连接多个其他表。 但是,为了获得更好的性能,应该限制要连接的表的数量(最好不要超过三个表)。第三,连接条件或连接谓词。连接条件出现在INNER JOIN
子句的ON
关键字之后。连接条件是将主表中的行与其他表中的行进行匹配的规则。
举个例子:
假设使用INNER JOIN
子句连接两个表:t1
和t2
,我们来简化上面的语法。
SELECT column_list
FROM t1
INNER JOIN t2 ON join_condition;
对于t1
表中的每一行,INNER JOIN
子句将它与t2
表的每一行进行比较,以检查它们是否都满足连接条件。当满足连接条件时,INNER JOIN
将返回由t1
和t2
表中的列组成的新行。
请注意,t1
和t2
表中的行必须根据连接条件进行匹配。如果找不到匹配项,查询将返回一个空结果集。当连接超过2个表时,也应用此逻辑。
以下维恩图说明了INNER JOIN子句的工作原理。结果集中的行必须出现在两个表中:t1和t2,如两个圆的交叉部分所示
1.1内连接常用写法
INNER JOIN … ON
select * from employee e
inner join department d on e.employee_id=d.department_id
where e.employee_id = '1';
等价于
select * from employee e,department d
where e.employee_id = d.department_id
and e.employee_id = '1';
1.2 三表内连接
SELECT article.aid,article.title,user.username,type.typename
FROM article
INNER JOIN user ON article.uid=user.uid
INNER JOIN type ON article.tid=type.tid
Leetcode题目:180. 连续出现的数字
编写一个 SQL 查询,查找所有至少连续出现三次的数字。
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
例如,给定上面的 Logs
表, 1 是唯一连续出现至少三次的数字。
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+
解答
select distinct a.Num ConsecutiveNums
from Logs a, Logs b,Logs c
where a.Num=b.Num and b.Num=c.Num
and a.Id+1=b.Id and b.Id+1=c.Id
where语句中进行三表内连接,并过滤找出三个连续值的
3.深入理解内连接逻辑
还是以上题为例,为了简化问题,我们只考虑双表连接:
select * from Logs a, Logs b
where a.Num=b.Num
得出结果:
{“headers”:[“Id”,“Num”,“Id”,“Num”],
“values”:[[1,1,1,1],[2,1,1,1],[3,1,1,1],[5,1,1,1],[1,1,2,1],[2,1,2,1],[3,1,2,1],[5,1,2,1],[1,1,3,1],[2,1,3,1],[3,1,3,1],[5,1,3,1],[4,2,4,2],[6,2,4,2],[7,2,4,2],[1,1,5,1],[2,1,5,1],[3,1,5,1],[5,1,5,1],[4,2,6,2],[6,2,6,2],[7,2,6,2],[4,2,7,2],[6,2,7,2],[7,2,7,2]]}
匹配步骤:
- 首先从表
a
的第一行考虑[1,1]因为匹配规则以Num为准,所以匹配到的结果应该是[[1,1,1,1],[1,1,2,1],[1,1,3,1],[1,1,5,1]] - 然后相同的思想匹配表
a
的其他行,得出上述的结果。