Mysql 函数参考和扩展:Mysql 常用函数和基础查询、 Mysql 官网
Mysql 语法执行顺序如下,一定要清楚!!!运算符相关,可前往 Mysql 基础语法和执行顺序扩展。
(8) select (9) distinct (11)<columns_name list> (1) from <left_table> (3) <join_type> join <right_table> (2) on <join_condition> (4) where <where_condition> (5) group by <group_by columns_name list> (6) with <rollup> (7) having <having_condition> (10) order by <order_by columns_name list> (12) limit <[offset,] rows> ;
数据准备
drop table if exists orderitems; create table if not exists orderitems ( order_num varchar(255) not null comment '商品订单号', item_price int(16) not null comment '售出价格', quantity int(16) not null comment '商品数量' ); insert orderitems values ('a0001', 10, 105), ('a0002', 1, 1100), ('a0002', 1, 200), ('a0013', 2, 1121), ('a0003', 5, 10), ('a0003', 1, 19), ('a0003', 7, 5); drop table if exists orders; create table if not exists orders ( order_num varchar(255) not null comment '商品订单号', cust_id varchar(255) not null comment '顾客id' ); insert `orders` values ('a0001', 'cust10'), ('a0003', 'cust1'), ('a0013', 'cust2');
子查询示例
子查询指一个查询语句嵌套在另一个查询语句内部的查询。又叫内部查询,相对于内部查询,包含内部查询的就称为外部查询。子查询外部必须是以下语句之一:select、insert、update、delete、set或者do。
标量子查询:是指子查询返回的是单一值的标量,如一个数字或一个字符串,也是子查询中最简单的返回形式。
可以使用 =、>、<、>=、<=、<>、! 这些操作符对子查询的标量结果进行比较。
# 单行单列,单一值 select order_num, item_price, quantity from orderitems where quantity = (select max(quantity) from orderitems); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0013 | 2 | 1121 | +-----------+------------+----------+
行子查询:指子查询返回的结果集是单行多列,该子查询的结果通常是对表的某行数据进行查询而返回的结果集。
# 单行多列 select order_num, item_price, quantity from orderitems where (order_num,item_price) = (select order_num,item_price from orderitems where quantity = 1121); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0013 | 2 | 1121 | +-----------+------------+----------+
列子查询:指子查询返回的结果集是多行单列,该结果通常来自对表的某个字段查询返回。
可以使用 in、not in、any、some 和 all操作符:
- in:判断是否在这个集合中,如果在True,否则返回False。
- not in:判断是否不在这个集合中,如果不在True,否则返回False。
- any:需要和单行比较操作符一起使用,和子查询返回的某一个值比较,如果其中有符合,则返回True。(比最小大就行)
- some:实际上是any的别名,作用相同,一般常使用any。
- all:需要和单行比较操作符一起使用,和子查询返回的所有值比较,如果所有都符合,则返回True。(比最大还大)
# 多行单列 select * from orderitems where quantity > any(select quantity from orderitems where order_num = 'a0002'); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0002 | 1 | 1100 | | a0013 | 2 | 1121 | +-----------+------------+----------+ select * from orderitems where quantity > all(select quantity from orderitems where order_num = 'a0002'); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0013 | 2 | 1121 | +-----------+------------+----------+
表子查询:指子查询返回的结果集是多行多列的一个表数据。
# 多行多列 select order_num, item_price, quantity from orderitems where (order_num,item_price,quantity) in (select order_num, item_price, quantity from orderitems where order_num = 'a0002'); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0002 | 1 | 1100 | | a0002 | 1 | 200 | +-----------+------------+----------+
关联子查询:如果子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表,并进行了条件关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称之为关联子查询 。
按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。
select * from orderitems as a where quantity > (select avg(quantity) from orderitems as b where a.order_num = b.order_num); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0002 | 1 | 1100 | | a0003 | 1 | 19 | +-----------+------------+----------+
exists
和not exists
子查询:
exists
:表示如果存在某种条件,则返回True,否则返回False。not exists
:表示如果不存在某种条件,则返回True,否则返回False。
select * from orderitems as a where exists(select * from orders as b where a.order_num = b.order_num); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0001 | 10 | 105 | | a0013 | 2 | 1121 | | a0003 | 5 | 10 | | a0003 | 1 | 19 | | a0003 | 7 | 5 | +-----------+------------+----------+ select * from orderitems as a where not exists(select * from orders as b where a.order_num = b.order_num); +-----------+------------+----------+ | order_num | item_price | quantity | +-----------+------------+----------+ | a0002 | 1 | 1100 | | a0002 | 1 | 200 | +-----------+------------+----------+
子查询的执行效率不高,尽量少使用子查询,可以使用多表连接查询代替子查询,多表连接查询不需要建立临时表,其速度比子查询要快。