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 |
+-----------+------------+----------+
子查询的执行效率不高,尽量少使用子查询,可以使用多表连接查询代替子查询,多表连接查询不需要建立临时表,其速度比子查询要快。