sql语句执行顺序(mysql为例)
测试数据表
- slugs
CREATE TABLE `slugs` (
`slug_id` int(11) NOT NULL AUTO_INCREMENT,
`slug_name` varchar(255) DEFAULT '',
`slug_type` tinyint(1) DEFAULT '1' COMMENT '类型1分类,2标签,3地区',
PRIMARY KEY (`slug_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
slug_id | slug_name | slug_type |
---|---|---|
3 | 资讯 | 1 |
4 | 旅游 | 3 |
5 | 海外 | 2 |
6 | 香港 | 2 |
7 | 内地 | 2 |
8 | 汽车 | 3 |
9 | 财经 | 3 |
10 | 民生 | 3 |
- posts
post_id | post_name |
---|---|
1 | 日本汽车公司造假召回 |
2 | 河南多地联系白天无降水 |
3 | 港币压提前加息 |
4 | 台湾十一旅游人数减少 |
5 | 北京长城到处是人 |
6 | 特朗普又发推文退群了 |
7 | 测试 |
- post_slugs
post_id | slug_id |
---|---|
1 | 3 |
1 | 5 |
1 | 8 |
2 | 3 |
2 | 7 |
2 | 10 |
3 | 6 |
3 | 9 |
4 | 2 |
4 | 3 |
5 | 3 |
5 | 7 |
6 | 3 |
6 | 5 |
几种连表方式
-
inner join,可缩写成join.
SELECT columns FROM TableA INNER JOIN TableB ON A.columnName = B.columnName;
返回A,B数据columnName 相同的数据,做等值连接。 -
left outer join,常用缩写 left join
SELECT columns FROM TableA LEFT OUTER JOIN TableB ON A.columnName = B.columnName
返回以A为主表所有数据以及B表满足条件的数据,以NULL补足数据SELECT columns FROM TableA LEFT OUTER JOIN TableB ON A.columnName = B.columnName WHERE B.columnName IS NULL
返回在A表出现,B表不出现的数据。 -
right outer join,常用缩写 right join
SELECT columns FROM TableA RIGHT OUTER JOIN TableB ON A.columnName = B.columnName
返回以A为主表所有数据以及B表满足条件的数据,以NULL补足数据SELECT columns FROM TableA RIGHT OUTER JOIN TableB ON A.columnName = B.columnName WHERE B.columnName IS NULL
返回在A表出现,B表不出现的数据。 -
Full [Outer] Join
SELECT columns FROM TableA FULL JOIN TableB ON A.columnName = B.columnName
返回A,B表数据并集。SELECT columns FROM TableA FULL JOIN TableB ON A.columnName = B.columnName
WHERE A.columnName IS NULL OR B.columnName IS NULL 返回A,B表数据并集-A,B表交集。
参考文章:(THE SEVEN TYPES OF SQL JOINS)[https://teamsql.io/blog/?p=923]
sql语句执行顺序
1.FROM:对FROM子句中前两个表执行笛卡尔积 生成虚拟表VT1
2.ON:对VT1表应用ON筛选器 只有满足
(8) SELECT (9) DISTINCT (11)
参考文章:(sql 语句的执行顺序)[https://segmentfault.com/a/1190000009456758]
连表操作
- select a,b,select a,b产生的结果是a,b两个表的笛卡尔积。
- select a join b,select a join b产生的结果是a,b两个表的笛卡尔积。(inner join 也是)
- left join,right join 不能没有on条件。select a left join b on 1=1,select a right join b on 1=1产生的结果是a,b两个表的笛卡尔积。
- select a,b的过滤:
SELECT * from posts,post_slugs where post_slugs.post_id=posts.post_id
生成的结果和SELECT * from posts join post_slugs on post_slugs.post_id=posts.post_id
结果相同。但是根据sql语句执行顺序,from的两个表会先生成迪卡尔积虚表。在实例中,虚表的大小7x14=98。再从98条记录中根据where条件过滤。但是以join方式的连表操作,执行顺序是先从posts表获取数据,再根据on条件过滤posts数据,post_slugs数据,根据join方式插入保留数据。所以join连表操作where需要过滤的数据是7+14条记录。
评论