9. SELECT TOP
SELECT TOP 语句用于在 SQL 中限制返回的结果集中的行数, 它通常用于只需要查询前几行数据的情况,尤其在数据集非常大时,可以显著提高查询性能。
9.1 语法
SQL
SELECT column1, column2, ...
FROM table_name
LIMIT number
参数说明:
- column1, column2, ...:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
- number: 要限制的范围
9.2 示例
Websites表:
id | name | url | alexa | country |
---|---|---|---|---|
1 | 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 | https://www.facebook.com/ | 3 | USA |
1.从 "Websites" 表中选取头两条记录:
SQL
SELECT *
FROM Websites
LIMIT 2
2.从 websites 表中选取前面百分之 50 的记录:
SQL
SELECT TOP 50 PERCENT
FROM Websites
10. JOIN
SQL join 用于把来自两个或多个表的行结合起来。
下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。
类型 | 含义 |
---|---|
INNER JOIN | 返回两个表中满足连接条件的交集 |
LEFT JOIN | 返回左表中的所有记录,即使右表中没有匹配的记录(保留左表) |
RIGHT JOIN | 返回右表中的所有记录,即使左表中没有匹配的记录(保留右表) |
FULL OUTER JOIN | 返回两个表的并集,包含匹配和不匹配的记录 |
CROSS JOIN | 返回两个表的笛卡尔积,每条左表记录与右表记录进行组合 |
SELF JOIN | 将一个表与自身连接 |
NATURAL JOIN | 基于同名字段自动匹配连接的表 |
10.1 INNER JOIN
INNER JOIN 是 SQL 中最常用的连接方式之一,用于从多个表中根据它们之间的关系提取匹配的记录。
INNER JOIN 关键字在表中存在至少一个匹配时返回行,返回的是两个表中满足连接条件的交集,即同时存在于两个表中的数据。
INNER JOIN 和JOIN是相同的。
10.1.1 语法
SQL
SELECT column1, column2, ...
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name
参数说明:
- column1, column2, ...:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table1:要连接的第一个表。
- table2:要连接的第二个表。
10.1.2 示例
Websites表:
id | name | url | alexa | country |
---|---|---|---|---|
1 | 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 | https://www.facebook.com/ | 3 | USA |
"access_log" 网站访问记录表:
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 |
请注意,"Websites" 表中的 "id" 列指向 "access_log" 表中的字段 "site_id"。上面这两个表是通过 "site_id" 列联系起来的。
1.将两表连接,输出id,name,count和date 信息
SQL
SELECT W.id, W.name, A.count, A.date
FROM Websites AS W
INNER JOIN access_log AS A
ON W.id = A.site_id
10.2 LEFT JOIN
LEFT JOIN 是 SQL 中的一个连接关键字,用于从多个表中提取数据。
LEFT JOIN 与 INNER JOIN 不同之处在于,LEFT JOIN 会返回左表中的所有记录,即使在右表中没有匹配的记录。
LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。
10.2.1 语法
SQL
SELECT column_name
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name
参数说明:
- column1, column2, ...:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table1:要连接的第一个表。
- table2:要连接的第二个表。
返回左表中的所有记录,即使右表没有匹配的数据。
如果右表没有匹配的记录,结果中该行右表字段为 NULL。
10.2.2 示例
Websites表:
id | name | url | alexa | country |
---|---|---|---|---|
1 | 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 | https://www.facebook.com/ | 3 | USA | |
7 | stackoverflow | http://stackoverflow.com/ | 0 | IND |
"access_log" 网站访问记录表:
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 |
请注意,"Websites" 表中的 "id" 列指向 "access_log" 表中的字段 "site_id"。上面这两个表是通过 "site_id" 列联系起来的。
1.返回所有网站及他们的访问量(如果有的话)。
SQL
SELECT W.url, A.count, A.date
FROM Websites AS W
LEFT JOIN access_log AS A
ON W.id = A.site_id
ORDER BY A.count DESC
LEFT JOIN 关键字从左表(Websites)返回所有的行,即使右表(access_log)中没有匹配。
10.3 RIGHT JOIN
RIGHT JOIN 是 SQL 中的一个连接关键字,用于从多个表中提取数据。
与 LEFT JOIN 类似,但其行为相反:RIGHT JOIN 会返回右表中的所有记录,即使左表中没有匹配的记录。
RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。
10.3.1 语法
SQL
SELECT column_name
FROM table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name
参数说明:
- column1, column2, ...:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table1:要连接的第一个表。
- table2:要连接的第二个表。
保留右表的所有记录:即使左表中没有匹配的记录,也会在结果中包含右表的所有记录。
左表未匹配时填充 NULL:如果左表中没有对应的记录,用 NULL 填充左表的列。
10.3.2 示例
Websites表:
id | name | url | alexa | country |
---|---|---|---|---|
1 | 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 | https://www.facebook.com/ | 3 | USA | |
7 | stackoverflow | http://stackoverflow.com/ | 0 | IND |
"access_log" 网站访问记录表:
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 | 111 | 2016-03-19 |
请注意,"Websites" 表中的 "id" 列指向 "access_log" 表中的字段 "site_id"。上面这两个表是通过 "site_id" 列联系起来的。
1.返回网站的访问记录。
SQL
SELECT W.name, A.count, A.date
FROM Websites AS W
RIGHT JOIN access_log AS A
ON A.site_id = W.id
ORDER BY A.count DESC
RIGHT JOIN 关键字从右表(access_log)返回所有的行,即使左表(Websites)中没有匹配。
10.4 FULL OYTER JOIN
FULL OUTER JOIN 是 SQL 中的一种连接方式,用于同时保留两个表中所有的记录,即使其中一方没有匹配项。
FULL OUTER JOIN 结果包括两个表中满足条件的记录(交集部分)以及不满足条件的记录(并集中的非交集部分)。 如果某条记录在一张表中存在,而在另一张表中没有匹配项,则该记录的缺失列会以 NULL 填充。
FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行。
FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。
10.3.1 语法
SQL
SELECT column_name
FROM table1
FULL OUTER JOIN table2
ON table1.column_name = table2.column_name
参数说明:
- column1, column2, ...:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table1:要连接的第一个表。
- table2:要连接的第二个表。
返回两个表的并集:包含所有匹配和未匹配的记录。
未匹配的记录填充 NULL:如果某条记录在一张表中没有匹配项,则其对应的字段以 NULL 表示。
对等性:FULL OUTER JOIN 包含了 LEFT JOIN 和 RIGHT JOIN 的结果。
10.4.2 示例
Websites表:
id | name | url | alexa | country |
---|---|---|---|---|
1 | 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 | https://www.facebook.com/ | 3 | USA | |
7 | stackoverflow | http://stackoverflow.com/ | 0 | IND |
"access_log" 网站访问记录表:
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 |
请注意,"Websites" 表中的 "id" 列指向 "access_log" 表中的字段 "site_id"。上面这两个表是通过 "site_id" 列联系起来的。
1.返回网站的访问记录。
SQL
SELECT W.name, A.count, A.date
FROM Websites AS W
FULL OUTER JOIN access_log AS A
ON A.site_id = W.id
ORDER BY A.count DESC
FULL OUTER JOIN 关键字返回左表(Websites)和右表(access_log)中所有的行。如果 "Websites" 表中的行在 "access_log" 中没有匹配或者 "access_log" 表中的行在 "Websites" 表中没有匹配,也会列出这些行。
11. UNION
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。它可以从多个表中选择数据,并将结果集组合成一个结果集。使用 UNION 时,每个 SELECT 语句必须具有相同数量的列,且对应列的数据类型必须相似。
11.1 语法
SQL
SELECT column1, column2, ...
FROM table1
UNION
SELECT cloumn1, column2,..
FROM table2
参数说明:
- column1, column2, ...:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
UNION 操作符默认会去除重复的记录,如果需要保留所有重复记录,可以使用 UNION ALL 操作符。
SQL
SELECT column1, column2, ...
FROM table1
UNION ALL
SELECT cloumn1, column2,..
FROM table2
注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
11.2 示例
Websites表:
id | name | url | alexa | country |
---|---|---|---|---|
1 | 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 | https://www.facebook.com/ | 3 | USA |
"apps" APP 的数据:
id | app_name | url | country |
---|---|---|---|
1 | QQ APP | http://im.qq.com/ | CN |
2 | 微博 APP | http://weibo.com/ | CN |
3 | 淘宝 APP | https://www.taobao.com/ | CN |
1.从 "Websites" 和 "apps" 表中选取所有不同的country(只有不同的值):
SQL
SELECT country
FROM Websites
UNION
SELECT country
FROM apps
ORDER BY country
2.从 "Websites" 和 "apps" 表中选取所有的country(也有重复的值):
SQL
SELECT country
FROM Websites
UNION ALL
SELECT country
FROM apps
ORDER BY country
- 从 "Websites" 和 "apps" 表中选取所有的中国(CN)的数据(也有重复的值):
SQL
SELECT country, name
FROM Websites
WHERE country = 'CN'
UNION ALL
SELECT country, app_name
FROM apps
WHERE country = 'CN'
ORDER BY country
12. INSERT INTO SELECT
INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。
12.1 语法
SQL
INSERT INTO table2 (column_name)
SELECT column_name
FROM table1
参数说明:
- column1, column2, ...:要选择的字段名称,可以为多个字段。如果不指定字段名称,则会选择所有字段。
- table_name:要查询的表名称。
12.2 示例
Websites表:
id | name | url | alexa | country |
---|---|---|---|---|
1 | 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 | https://www.facebook.com/ | 3 | USA |
"apps" APP 的数据:
id | app_name | url | country |
---|---|---|---|
1 | QQ APP | http://im.qq.com/ | CN |
2 | 微博 APP | http://weibo.com/ | CN |
3 | 淘宝 APP | https://www.taobao.com/ | CN |
1.复制 "apps" 中的数据插入到 "Websites" 中:
SQL
INSERT INTO Websites (name, country)
SELECT app_name, country
FROM apps
2.只复 id=1 的数据到 "Websites" 中:
SQL
INSERT INTO Websites (name, country)
SELECT app_name, country
FROM apps
WHERE id =1