先创建一个名为 website
的数据表作为示例使用。
1 2 3 4 5 6 7 8 9 10
| +----+--------------+---------------------------+-------+---------+ | id | name | url | alexa | country | +----+--------------+---------------------------+-------+---------+ | 1 | Google | https://www.google.cm/ | 1 | USA | | 2 | 淘宝 | https://www.taobao.com/ | 13 | CN | | 3 | 菜鸟教程 | http://www.runoob.com/ | 4689 | CN | | 4 | 微博 | http://weibo.com/ | 20 | CN | | 5 | Facebook | https://www.facebook.com/ | 3 | USA | | 7 | stackoverflow | http://stackoverflow.com/ | 0 | IND | +----+---------------+---------------------------+-------+---------+
|
SELECT TOP,LIMIT,ROWNUM 子句
SELECT TOP
子句用于规定要返回的记录的数目,不过并非所有的数据库系统都支持 SELECT TOP
语句。
MySQL
支持 LIMIT
语句来选取指定的条数数据
Oracle
可以使用 ROWNUM
来选取。
1 2 3 4 5 6 7 8 9 10 11 12
| select top n col1, col2 from table_name;
select col1, col2 from table_name limit n;
select col1, col2 from table_name where ROWNUM <= n;
select top 50 percent col1, col2 from table_name;
|
别名
可以为表名称或列名称指定别名。大多数情况,是为了让列名称的可读性更强。
1
| select country as co from website;
|
得到
1 2 3 4 5 6 7 8
| | co | |-----| | USA | | CN | | CN | | CN | | USA | | IND |
|
利用别名与 CONCAT 将查询结果的列合并
CONCAT
可以把查询结果的列合并,但是其合并的字段名没有意义,可以通过别名赋予其意义
1
| select name, concat(url, ',', alexa, ',', country) as web_info from website;
|
1 2 3 4 5 6 7 8
| | name | web_info | |--------------|----------------------------------| | Google | https://www.google.cm/,1,USA | | 淘宝 | https://www.taobao.com/,13,CN | | 菜鸟教程 | http://www.runoob.com/,4689,CN | | 微博 | http://weibo.com/,20,CN | | Facebook | https://www.facebook.com/,3,USA | | stackoverflow | http://stackoverflow.com/,0,IND |
|
JOIN 子句
JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。JOIN 一共有 7 种用法,最常见的 JOIN
类型为 INNER JOIN
,意为从多个表中返回满足条件的所有行。
再创建一个新表 access_log
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| +-----+---------+-------+------------+ | aid | site_id | count | date | +-----+---------+-------+------------+ | 1 | 1 | 45 | 2016-05-10 | | 2 | 3 | 100 | 2016-05-13 | | 3 | 1 | 230 | 2016-05-14 | | 4 | 2 | 10 | 2016-05-14 | | 5 | 5 | 205 | 2016-05-14 | | 6 | 4 | 13 | 2016-05-15 | | 7 | 3 | 220 | 2016-05-15 | | 8 | 5 | 545 | 2016-05-16 | | 9 | 3 | 201 | 2016-05-17 | | 10 | 6 | 333 | 2016-05-17 | +-----+---------+-------+------------+
|
执行
1 2 3 4
| select website.name, access_log.count from website join access_log on website.id = access_log.site_id;
|
结果
1 2 3 4 5 6 7 8 9 10 11 12 13
| +--------------+---------+ | name | count | +--------------+---------+ | Google | 45 | | 菜鸟教程 | 100 | | Google | 230 | | 淘宝 | 10 | | Facebook | 205 | | 微博 | 13 | | 菜鸟教程 | 220 | | Facebook | 545 | | 菜鸟教程 | 201 | +--------------+---------+
|
外连接(OUTER JOIN)
取得两张表中满足存在连接匹配关系的记录,以及某张表(或两张表)中不满足匹配关系的记录。
外连接又分为左连接,右连接,全连接:
左外接(LEFT JOIN)
在内连接的基础之上还显示左表不满足匹配关系的记录,不存在的结果为 NULL 。
1 2 3
| select website.name, access_log.count from website left join access_log on website.id = access_log.site_id;
|
得
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| +--------------+---------+ | name | count | +--------------+---------+ | Google | 45 | | 菜鸟教程 | 100 | | Google | 230 | | 淘宝 | 10 | | Facebook | 205 | | 微博 | 13 | | 菜鸟教程 | 220 | | Facebook | 545 | | 菜鸟教程 | 201 | | stackoverflow| NULL | --> 右表没匹配也会记录 +--------------+---------+
|
右外接(RIGHT JOIN)
在内连接的基础之上还显示右表不满足匹配关系的记录,不存在的结果为 NULL 。
1 2 3
| select website.name, access_log.count from website right join access_log on website.id = access_log.site_id;
|
得
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| +--------------+---------+ | name | count | +--------------+---------+ | Google | 45 | | 菜鸟教程 | 100 | | Google | 230 | | 淘宝 | 10 | | Facebook | 205 | | 微博 | 13 | | 菜鸟教程 | 220 | | Facebook | 545 | | 菜鸟教程 | 201 | | NULL | 333 | --> 左表没匹配也会记录 +--------------+---------+
|
全外连(FULL OUTER JOIN)
在内连接的基础之上,左右表不满足匹配关系的记录都显示,不存在的结果为 NULL 。
1 2 3 4
| select website.name, access_log.count from website full outer join access_log on website.id = access_log.site_id;
|
得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| +--------------+---------+ | name | count | +--------------+---------+ | Google | 45 | | 菜鸟教程 | 100 | | Google | 230 | | 淘宝 | 10 | | Facebook | 205 | | 微博 | 13 | | 菜鸟教程 | 220 | | Facebook | 545 | | 菜鸟教程 | 201 | | stackoverflow| NULL | --> 右表没匹配 | NULL | 333 | --> 左表没匹配 +--------------+---------+
|
交叉连接(CROSS JOIN)
交叉连接,又名笛卡儿积,其概念如下:
有两个集合 A = {0,1} , B = {2,3,4}
那么,集合 A 与 B 的笛卡儿积 A * B 得到的结果是
A * B = {(0,2)、(1,2)、(0,3)、(1,3)、(0,4)、(1,4)};
B * A = {(2,0)、{2,1}、{3,0}、{3,1}、{4,0}、(4,1)};
上面 A * B 和 B * A 的结果就可以称为两个集合相乘的笛卡尔积
我们可以得出结论,A 集合和 B 集合相乘,包含了集合 A 中的元素和集合 B 中元素之和,也就是 A 元素的个数 x B 元素的个数
对于 SQL,笛卡儿积就是把左表的每一条数据(设共有 m 条)与右表的每一条数据(设共有 n 条)做拼接,因此其结果总共有 m x n 条。
1
| select * from left_table cross join right_table;
|
UNION 操作符
UNION
操作符用于合并两个或多个 SELECT 语句的结果集。
其中,每个 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。
1 2 3
| select id from website union select site_id from access_log;
|
得
1 2 3 4 5 6 7 8 9
| | id | |----| | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 |
|
UNION
操作符默认会选取不同的值。如果允许重复的值,请使用 UNION ALL。
1 2 3
| select id from website union all select site_id from access_log;
|
得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| | id | |----| | 1 | | 1 | | 1 | | 2 | | 2 | | 3 | | 3 | | 3 | | 3 | | 4 | | 4 | | 5 | | 5 | | 5 | | 6 | | 7 |
|