SQL的条件查询
四、SQL查询
DQL:数据查询语言
常见的查询条件
条件语句 | 简介 |
---|---|
= != > < >= <= 比较运算 | 列名 运算符 值 |
between..and.. | 范围 id between 2 and 4 |
in /not in | 成员 id in (2,4) |
and | && | 逻辑与,查询结果必须满足所有条件 |
or | || | 逻辑或,查询结果满足任意一个条件 |
not | ! | 逻辑非,查询所有不满足条件的结果 |
is null | 查询结果为空的值 |
is not null | 查询结果不为空的值 |
order by | 排序 order by id 逆序从大到小使用desc |
like | 模糊查询 name like "%三%" ,其中% 表示任意个任意值 |
范围查询
分组查询
结果排序
结果分页
模糊查询
电商案例:
-- 1. 创建表结构
-- 用户表
CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL,age INT,gender ENUM('男', '女', '未知'),city VARCHAR(50),register_time DATETIME DEFAULT CURRENT_TIMESTAMP
);-- 商品表
CREATE TABLE products (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100) NOT NULL,category VARCHAR(50) NOT NULL,price DECIMAL(10,2) NOT NULL CHECK (price > 0),stock INT NOT NULL DEFAULT 0 CHECK (stock >= 0)
);-- 订单表
CREATE TABLE orders (id INT PRIMARY KEY AUTO_INCREMENT,user_id INT NOT NULL,product_id INT NOT NULL,quantity INT NOT NULL CHECK (quantity > 0),total_amount DECIMAL(10,2) NOT NULL CHECK (total_amount > 0),status ENUM('待付款', '已付款', '已发货', '已完成', '已取消') DEFAULT '待付款',create_time DATETIME DEFAULT CURRENT_TIMESTAMP,-- 外键关联FOREIGN KEY (user_id) REFERENCES users(id),FOREIGN KEY (product_id) REFERENCES products(id)
);-- 2. 插入测试数据
-- 插入用户数据
INSERT INTO users (username, age, gender, city, register_time) VALUES
('张三', 28, '男', '北京', '2023-01-15 09:30:00'),
('李四', 22, '女', '上海', '2023-02-20 14:15:00'),
('王五', 35, '男', '广州', '2023-03-05 10:00:00'),
('赵六', 19, '女', '北京', '2023-04-18 16:45:00'),
('孙七', 42, '男', '深圳', '2023-05-10 11:20:00');-- 插入商品数据
INSERT INTO products (name, category, price, stock) VALUES
('iPhone 14', '手机', 5999.00, 50),
('华为MateBook', '电脑', 6999.00, 30),
('小米手环', '智能设备', 199.00, 100),
('Nike运动鞋', '服装', 699.00, 80),
('机械键盘', '电脑配件', 299.00, 60);-- 插入订单数据
INSERT INTO orders (user_id, product_id, quantity, total_amount, status, create_time) VALUES
(1, 1, 1, 5999.00, '已完成', '2023-06-01 10:30:00'),
(1, 3, 2, 398.00, '已完成', '2023-06-15 15:45:00'),
(2, 4, 1, 699.00, '已完成', '2023-06-05 09:15:00'),
(3, 2, 1, 6999.00, '已发货', '2023-06-20 11:20:00'),
(4, 5, 1, 299.00, '待付款', '2023-06-25 16:30:00'),
(5, 1, 1, 5999.00, '已取消', '2023-06-18 14:00:00'),
(2, 3, 1, 199.00, '已完成', '2023-06-10 10:00:00'),
(3, 5, 2, 598.00, '已完成', '2023-06-08 13:25:00');
范围查询(比较运算)
序号 | 关键字 | 说明 | 示例 |
---|---|---|---|
1 | = | 等于 | select * from users where gender = '男'; |
2 | !=/<> | 不等于 | select * from products where category != '服装'; |
3 | >/< | 大于 / 小于 | select * from orders where total_amount > 2000; |
4 | >=/<= | 大于等于 / 小于等于 | select * from users where age <= 30; |
范围查询(数字、日期)
序号 | 关键字 | 说明 | 示例 |
---|---|---|---|
1 | between ... and ... | 在指定范围内(包含边界) | select * from products where price between 500 and 5000; |
2 | in (...) | 匹配列表中的任意值 | select * from users where city in ('广州', '深圳'); |
3 | not in (...) | 不匹配列表中的任意值 | select * from orders where status not in ('已取消', '待付款'); |
模糊查询 like
序号 | 关键字 | 说明 | 示例 |
---|---|---|---|
1 | like | 模糊匹配,%匹配任意字符,_匹配单个字符 | select * from products where name like '华为%'; select * from users where username like '_三%'; |
空值判断(为空、不为空)
序号 | 关键字 | 说明 | 示例 |
---|---|---|---|
1 | is null | 字段值为 null | select * from users where age is null; |
2 | is not null | 字段值不为 null | select * from products where stock is not null; |
逻辑组合(与或非)
序号 | 关键字 | 说明 | 示例 |
---|---|---|---|
1 | and | 同时满足多个条件 | select * from orders where status = '已完成' and quantity > 1; |
2 | or | 满足任意一个条件 | select * from users where age < 20 or gender = '未知'; |
3 | not | 条件取反 | select * from products where not price < 100; |
聚合筛选
条件类型 | 关键字 | 说明 | 示例 |
---|---|---|---|
聚合筛选 | having | 对分组结果筛选(需配合 group by) | select user_id, sum(amount) from orders group by user_id having sum(amount) > 5000; |
常用的聚合函数
函数名 | 简介 | 用法 |
---|---|---|
count( ) | 查询数量或次数 | select count(*) as '学生人数' from student where sex='女'; |
max( ) | 最大值 | select max(grade) from score; |
min( ) | 最小值 | select min(grade) from score; |
avg( ) | 平均值 | select avg(grade) from score; |
sum( ) | 求和 | select sum(grade) from score; |
子查询、去重
子查询:也叫嵌套查询,一般将一个select查询的结果作为另一个查询的条件进行查询。
条件类型 | 关键字 | 说明 | 示例 |
---|---|---|---|
子查询 | exists(用于检查括号内的子查询是否返回) | 子查询有结果则成立 | select * from users where exists (select 1 from orders where user_id = users.id); |
子查询 | not exists | 子查询无结果则成立 | select * from products where not exists (select 1 from orders where product_id = products.id); |
去重 | distinct | 筛选唯一值 | select distinct city from users; |
select * from users where exists(select 1 from orders where user_id=users.id);
-- 查询所有在 orders 表中存在订单记录的用户
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
-- 等价于上面的例子
分组查询group by
select user_id,sum(total_amount) from orders group by user_id having sum(total_amount)>5000;
-- 统计每个用户的总订单金额,并筛选出总金额超过 5000 的用户
-- having 在这里用于过滤分组后的聚合结果(与 WHERE 不同,WHERE 用于分组前过滤行)
排序查询order by
关键字 | 说明 | 示例 |
---|---|---|
order by 字段 asc | 按指定字段升序排列(默认) | select * from products order by price asc; |
order by 字段 desc | 按指定字段降序排列 | select * from orders order by create_time desc; |
多字段排序 | 先按第一个字段排,再按第二个字段排 | select * from users order by city asc, age desc; |
分页排序limit
语法:Select 字段列表 from 表名 where 条件(可选)order by 排序字段 (建议加,保证分页顺序稳定)limit 初始位置, 每页条数;
关键字 | 说明 | 示例 |
---|---|---|
limit 条数 | 只返回前 n 条记录 | select * from products order by price desc limit 5; |
limit 起始位置, 条数 | 从指定位置开始返回 n 条记录(起始从 0 开始) | select * from orders order by id limit 10, 5; -- 第 11-15 条记录 |
分页公式 | 第 n 页(每页 m 条):limit (n-1)*m, m | select * from users limit 20, 10; -- 第 3 页,每页 10 条 |
select * from products order by price desc limit 20,10
-- 按价格从高到低排序所有商品,然后跳过前 20 条,取接下来的 10 条 —— 也就是查询第 3 页的数据(每页 10 条)
关键说明
排序(ORDER BY):
必须放在
WHERE
之后,LIMIT
之前可指定多个排序字段,用逗号分隔
字符串按字典顺序排序,日期按时间先后排序
分页(LIMIT):
语法格式:
LIMIT [offset,] row_count
,offset可选(默认0)分页查询通常需要配合
ORDER BY
使用,否则分页结果可能不稳定计算第N页数据(每页显示M条)的公式:
LIMIT (N-1)*M, M
组合使用: 实际场景中经常组合多种条件,例如:
-- 分页查询价格100-1000元的"智能设备",按价格降序,取第2页(每页5条)
SELECT * FROM products
WHERE category = '智能设备' AND price BETWEEN 100 AND 1000
ORDER BY price DESC
LIMIT 5, 5;