多表连接查询
多表连接,就是将几张表拼接为一张表,然后进行查询,先来看基本语法:
SELECT col1,col2 FROM t1 INNER/LEFT/RIGHT JOIN t2 ON 连接条件(t1.col=t2.col) ;
接下来,来研究连接时的几种情况。
交叉连接
交叉连接时,不使用任何匹配条件,生成笛卡尔积:
SELECT * FROM employee,department; +----+--------+-----+--------+--------+----+-----------+ | id | NAME | age | gender | dep_id | name | | 1 | 小黄 18 | male | | 人事部 2 | 财务部 3 | 行政部 4 | 运营部 | 小李 19 | 小红 20 | female | 小兰 5 | 小六 32 6 | 小王 23 7 | 小华 52 28 rows in set (0.00 sec)
由展示结果可以看到,笛卡尔积的结果是左表的每条记录都跟右表的每条记录都连接一次,这就是所谓的笛卡尔积的结果。虽然看起来没啥用,但它确是一切连接的基础。
内连接
内连接(INNER JOIN)是找几张表的交集,即根据条件筛选出来正确的结果。
emp.id,emp.name,emp.age,emp.dep_id,emp.gender,dep.id,dep.name FROM employee AS emp INNER JOIN department AS dep ON emp.dep_iddep.id; | name 6 rows 0.00 sec)
外连接之右连接
跟左连接正好相反,右连接(RIGHT JOIN)是以右表为准,如果左表中某些字段没有合适的结果,用NULL
补全;其本质是在内连接的基础上增加右表有结果而左表没有的记录(内连接时,这种情况的记录会忽略)。
AS emp RIGHT ----+--------+------+--------+--------+----+-----------+ | id | age | | | NULL NULL | 7 rows 0.00 sec)
由结果可知,记录展示以右表为准,因为右表没有id=5
的部门,所以,左表中dep_id=5
的记录不展示。
全外连接
全外连接,在内连接的基础上,展示左右表的所有的记录,而左右表中缺省记录以NULL
补全。
LEFT dep.id UNION 全外连接使用 union ----+--------+------+--------+--------+------+-----------+ NULL 8 rows 0.00 sec)
注意,MySQL中并没有全外连接的FULL JOIN
语法,而是借助UNION
语句实现。
这里复习下union
和union all
的区别,union
具有去重功能。
使用连表查询示例:
找出年龄大于20岁的员工及员工所在部门 emp.name,1)">ON emp.dep_id=dep.id WHERE emp.age>20; 查询世界上人口数量小于100人的城市名和国家名 country.name,city.name,city.population FROM city country ON city.countrycodecountry.code city.population<100; 查询城市shenyang的城市人口,所在国家(name)及国土面积(surfacearea) city.name,city.population,country.name,country.surfacearea WHERE city.name='shenyang';
子查询
子查询是将一个查询语句嵌套再另一个查询语句中的查询方式:
- 子查询的内层查询结果,可以作为外层查询语句提供查询条件。
- 子查询中可以包含
IN
、NOT IN
、AND
、ALL
、EXISTS
、NOT EXISTS
等关键字。 - 子查询中还可以包含比较运算符,如
=
、!=
、>
、<
等。
来看示例:
查询平均年龄在20以上的部门名称 NAME department WHERE id IN ( dep_id employee GROUP BYHAVING AVG(age) > 20); 查询财务部员工姓名 NAME WHERE dep_id id department WHERE NAME财务部'); 查询所有大于平均年龄的员工的年龄和姓名 NAME,age employee WHERE age >SELECT AVG(age) FROM employee);
查询中别名的应用
虽然之前也在使用别名,这里再次回顾下别名相关的知识。
别名共分为两类:
- 表别名
- 列别名
先来看列别名:
使用别名之前 WHERE city.name'; --------+------------+-------+-------------+ | name | population | name | surfacearea | Shenyang 4265200 | China 9572900.00 1 row 0.00 sec) 使用别名之后 city.name 城市名,city.population 城市人口,country.name 国家名,country.surfacearea 国土面积 ---------+--------------+-----------+--------------+ | 城市名 | 城市人口 | 国家名 | 国土面积 | Shenyang | China 0.01 sec)
列别名的优点就是自定义返回的字段名称,主要是显式好看些!不过不推荐如上文中使用中文,可能会出现意外情况!
当然,AS
也可以省略不写,效果一样的:
city.name 城市名,city.population 城市人口,country.name 国家名,country.surfacearea 国土面积 0.00 sec)
再来看表别名:
a.name,a.population,b.name,b.surfacearea AS a JOIN country b ON a.countrycodeb.code WHERE a.name; 表别名和列别名一起使用 a.name ';
别名的优点就是简化了编写SQL时的复杂性,因为有的表名和列名又臭又长!
原文地址:https://www.cnblogs.com/tracydzf
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。