1. 分组查询
-
GROUP BY 子句
GROUP BY 函数就是 SQL 中用来实现分组的函数,其用于结合聚合函数,能根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表
语法:
select column_name, aggregate_function(column_name) from table_name
where column_name operator value group by column;
实例如下:
mysql> SELECT `country`, COUNT(`country`) AS `teacher_count` FROM `teachers` GROUP BY `country` ORDER BY `teacher_count`, `country`;
+---------+---------------+
| country | teacher_count |
+---------+---------------+
| JP | 1 |
| UK | 1 |
| USA | 1 |
| CN | 2 |
+---------+---------------+
4 rows in set (0.04 sec)
-
HAVING 子句
使用 HAVING 子句时就经常与 GROUP BY 语句搭配使用
使用 WHERE 条件子句时会发现其不能与聚合函数联合使用,为解决这一点,SQL 中提供了 HAVING 子句。在使用时, HAVING 子句经常与 GROUP BY 联合使用,HAVING 子句就是对分组统计函数进行过滤的子句
HAVING 子句对于 GROUP BY 子句设置条件的方式其实与 WHERE 子句与 SELECT 的方式类似,语法也相近,但 WHERE 子句搜索条件是在分组操作之前,而 HAVING 则是在之后
语法:
select column_name , aggregate_function(column_name) from table_name
where column_name operator value
group by column_name having aggregate_function(column_name) operator value;
实例如下:
mysql> SELECT T.name, IFNULL(SUM(C.student_count),0) AS `student_count`
-> FROM courses C
-> RIGHT JOIN teachers T ON C.teacher_id = T.id
-> GROUP BY T.id
-> HAVING student_count < 3000
-> ORDER BY student_count, name;
+------------------+---------------+
| name | student_count |
+------------------+---------------+
| Linghu Cheng | 0 |
| Northern Beggar | 0 |
| Southern Omperor | 1520 |
+------------------+---------------+
3 rows in set (0.02 sec)
2. 简单子查询
什么是子查询呢?
当一个查询是另一个查询的条件时,称之为子查询
即在查询语句中的 WHERE 条件子句中,又嵌套了另一个查询语句
因此,子查询本质上就是一个完整的 SELECT 语句,它可以使一个 SELECT、INSERT INTO 语句、DELETE 语句或 UPDATE 语句嵌套在另一子查询中。子查询的输出可以包括一个单独的值(单行子查询)、几行值(多行子查询)、或者多列数据(多列子查询)
-
SELECT 语句中的子查询
语法:
select (columns_name) from table_name where operator (select columns_name
from table_name);
-
INSERT 语句中的子查询
语法:
insert into table_name select column_name from table_name [where value operator];
实例如下:
可以进行快速的数据备份。
insert into table1 select * from table2;
-
UPDATE 语句中的子查询
语法:
update table_name set column = new_value where column_name operator
(select column_name from table_name [ where value operator ]);
注意:在 UPDATE 语句的子查询中,子查询 SELECT 语句所用的表和 UPDATE 语句所要更改的表不能是同一张表!
-
DELETE 语句中的子查询
语法:
delete from table_name where column_name operator
(select column_name from table_ name [ where ]);
注意:在 DELETE 语句的子查询中,子查询 SELECT 语句所用的表和 DELETE 语句所要更改的表不能是同一张表!
3. 子查询进阶
- 内联视图子查询
SELECT 语句的语法,为:SELECT column_name FROM table_name ,结合我们前面学习的子查询的方法,我们是将子查询插入到列名 column_name 的位置,将子查询的结果作为列名,而本节我们将介绍的内联视图子查询,是将子查询插入到表名 table_name 的位置
内联视图子查询实际上就是将查询的结果集作为一个查询表,继续进行查询操作
语法:
select column_name from ([ select ]) where column_name = ([ select ])
实例如下:
select * from (select * from user where country = 'China') where age = (select min(age) from user);
- IN 操作符的多行子查询
使用 IN 操作符进行子查询,其实是将子查询返回的集合和外层查询得到的集合进行交集运算,这个结果可以是零个值,也可以是多个值。由此,最后可以查询出与列表中任意一个值匹配的行
语法:
select column_name from table_name where column_name in
(select column_name from table_name where column_name = value);
- ANY 操作符的多行子查询
操作符 ANY 属于逻辑运算符的一种,与 IN 运算符不同,ANY 必须和其它的比较运算符共同使用,其表示查询结果中的任意一个
在子查询中使用 ANY ,表示与子查询返回的任何值比较为真,则返回真
语法:
select column_name from table_name where column_name operator any
(select column_name from table_name where column_name = value);
- ALL 操作符的多行子查询
操作符 ALL 也属于逻辑运算符的一种,且都须与其它的比较运算符共同使用,其表示查询结果中的所有
在子查询中使用 ALL ,表示与子查询返回的所有值比较为真,则返回真
语法:
select column_name from table_name where column_name operator all
(select column_name from table_name where column_name = value);
- 多列子查询
当是单行多列
的子查询时,主查询语句的条件语句中引用子查询结果时可用单行比较符号(=,>,<,>=,<=, <> 等)来进行比较
当是多行多列
子查询时,主查询语句的条件语句中引用子查询结果时必须用多行比较符号(IN,ANY,ALL 等)来进行比较
例子如下:
mysql> SELECT `name`, `age`, `country`
-> FROM `teachers`
-> WHERE (`country`, `age`) IN (
-> SELECT `country`, MAX(`age`)
-> FROM `teachers`
-> GROUP BY `country`
-> );
+------------------+-----+---------+
| name | age | country |
+------------------+-----+---------+
| Eastern Heretic | 20 | UK |
| Northern Beggar | 21 | CN |
| Western Venom | 28 | USA |
| Southern Emperor | 21 | JP |
+------------------+-----+---------+
4 rows in set (0.06 sec)
- HAVING 子句中的子查询
例子如下:
mysql> SELECT `name`
-> FROM `teachers`
-> WHERE `id` IN (
-> SELECT `teacher_id`
-> FROM `courses`
-> GROUP BY `teacher_id`
-> HAVING AVG(`student_count`) > (
-> SELECT AVG(`student_count`)
-> FROM `courses`
-> )
-> );
+-----------------+
| name |
+-----------------+
| Eastern Heretic |
| Western Venom |
+-----------------+
2 rows in set (0.09 sec)
网友评论