join动作步骤
-
笛卡尔积(是逻辑步骤还是真实步骤?如果是真实步骤实在太占内存)
-
应用on筛选条件,注意
left join
不影响左边的基表,只影响右边的外表 -
添加外部行,
left join
后行数应该和基表的行数相等,在第二步没有关联起来的,右边加上null -
应用where筛选条件
例子
表main
表ext
select * from main left join ext on main.id=ext.id and ext.address<>'杭州';
结果就错了:
因为如上所说的第三步,加上了null的对应
改为如下就可以了
select * from main left join ext on main.id=ext.id where ext.address<>'杭州';
Leetcode 601 体育馆的人流量
这个题目是很好的表关联的考察
X 市建了一个新的体育馆,每日人流量信息被记录在这三列信息中:序号 (id)、日期 (visit_date)、 人流量 (people)。
请编写一个查询语句,找出人流量的高峰期。高峰期时,至少连续三行记录中的人流量不少于100。
例如,表 stadium:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 1 | 2017-01-01 | 10 |
| 2 | 2017-01-02 | 109 |
| 3 | 2017-01-03 | 150 |
| 4 | 2017-01-04 | 99 |
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-08 | 188 |
+------+------------+-----------+
对于上面的示例数据,输出为:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-08 | 188 |
+------+------------+-----------+
sql代码如下
思路:自体表2次join,考虑3种情况,第一种是在第一个,第二种是在中间,第三种是在第三个,这样会有重复的,所以查询的时候加了一个去重
select distinct a.* from stadium a join stadium b join stadium c on
(a.id+1=b.id and b.id+1=c.id
or
a.id-1=b.id and b.id-1=c.id
or
a.id-1=b.id and a.id+1=c.id)
where a.people>=100 and b.people>=100 and c.people>=100
order by a.id;
思考题
如果采用如下的语句形式,会如何?
select a.*,b.* from a left join b on 1=0
这样的语句会有返回值,而且a中所有行都会返回,而b中全部填null