一、WHERE子句语法格式详解
1.1 基础语法结构
WHERE子句是SELECT语句中的筛选条件部分,用于从表中提取满足特定条件的记录。
bash
sql
SELECT 列名1, 列名2, ...
FROM 表名
WHERE 条件表达式;
1.2 完整的SELECT语句结构
bash
sql
SELECT
[ALL | DISTINCT | DISTINCTROW]
select_expr [, select_expr ...]
FROM
table_references
[WHERE where_condition] -- WHERE子句位置
[GROUP BY {col_name | expr | position}]
[HAVING where_condition]
[ORDER BY {col_name | expr | position} [ASC | DESC]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}];
1.3 运算符优先级表
bash
优先级 运算符 描述
1 =, <>, !=, <, <=, >, >= 比较运算符
2 BETWEEN, LIKE, IN, IS NULL 特殊比较
3 NOT 逻辑非
4 AND 逻辑与
5 OR 逻辑或
二、带IN关键字的查询:多值匹配
2.1 基本语法格式
bash
sql
SELECT 列名 FROM 表名
WHERE 列名 IN (值1, 值2, 值3, ...);
2.2 实际应用示例
bash
sql
-- 示例表:员工表(employees)
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
department VARCHAR(30),
salary DECIMAL(10,2),
hire_date DATE
);
-- 插入示例数据
INSERT INTO employees VALUES
(1, '张三', '技术部', 8500, '2022-03-15'),
(2, '李四', '销售部', 7500, '2021-08-22'),
(3, '王五', '技术部', 9200, '2020-11-05'),
(4, '赵六', '市场部', 6800, '2023-01-30'),
(5, '孙七', '人事部', 6500, '2022-06-18'),
(6, '周八', '技术部', 8800, '2021-09-10');
示例1:查询指定部门的员工
sql
-- 查询属于技术部或销售部的员工
SELECT
id AS '员工编号',
name AS '姓名',
department AS '部门',
salary AS '薪资'
FROM employees
WHERE department IN ('技术部', '销售部');
查询结果:
text
员工编号 姓名 部门 薪资
1 张三 技术部 8500.00
2 李四 销售部 7500.00
3 王五 技术部 9200.00
6 周八 技术部 8800.00
bash
示例2:IN子查询的运用
sql
-- 查询薪资高于平均薪资的员工
SELECT
name AS '姓名',
salary AS '薪资'
FROM employees
WHERE salary IN (
SELECT salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees)
);
2.3 NOT IN的用法
bash
sql
-- 查询不在某些部门的员工
SELECT
name AS '姓名',
department AS '部门'
FROM employees
WHERE department NOT IN ('人事部', '市场部');
三、带BETWEEN AND的范围查询
3.1 基础语法格式
bash
sql
SELECT 列名 FROM 表名
WHERE 列名 BETWEEN 值1 AND 值2;
-- 等价于:WHERE 列名 >= 值1 AND 列名 <= 值2
3.2 实际应用示例
bash
sql
-- 示例表:学生成绩表(scores)
CREATE TABLE scores (
student_id INT,
student_name VARCHAR(50),
subject VARCHAR(20),
score INT,
exam_date DATE
);
INSERT INTO scores VALUES
(101, '张三', '数学', 85, '2023-06-15'),
(102, '李四', '数学', 92, '2023-06-15'),
(103, '王五', '数学', 78, '2023-06-15'),
(104, '赵六', '数学', 65, '2023-06-15'),
(105, '孙七', '数学', 88, '2023-06-15');
示例1:查询分数在某个区间的学生
sql
-- 查询数学成绩在80-90分之间的学生
SELECT
student_id AS '学号',
student_name AS '姓名',
score AS '数学成绩'
FROM scores
WHERE subject = '数学'
AND score BETWEEN 80 AND 90;
查询结果:
text
学号 姓名 数学成绩
101 张三 85
105 孙七 88
示例2:日期范围查询
sql
-- 查询2023年上半年入职的员工
SELECT
name AS '姓名',
department AS '部门',
hire_date AS '入职日期'
FROM employees
WHERE hire_date BETWEEN '2023-01-01' AND '2023-06-30';
示例3:NOT BETWEEN的用法
sql
-- 查询薪资不在8000-9000范围内的员工
SELECT
name AS '姓名',
salary AS '薪资'
FROM employees
WHERE salary NOT BETWEEN 8000 AND 9000;
3.3 注意事项
bash
sql
-- BETWEEN包含边界值
WHERE score BETWEEN 80 AND 90 -- 包含80和90
-- 对于日期,注意时间部分
WHERE date_column BETWEEN '2023-01-01' AND '2023-01-31'
-- 等价于:'2023-01-01 00:00:00' 到 '2023-01-31 23:59:59'
四、带LIKE关键字的模糊查询
4.1 通配符说明
bash
通配符 描述 示例
% 匹配任意多个字符(0个或多个) 张% 匹配"张三"、"张"
_ 匹配单个字符 _三 匹配"张三"、"李三"
[charlist] 匹配字符列表中的任意一个 [张李]三 匹配"张三"、"李三"
[^charlist] 匹配不在字符列表中的任意一个 [^张李]三 匹配"王三"、"赵三"
4.2 实际应用示例
bash
sql
-- 示例表:图书表(books)
CREATE TABLE books (
book_id INT,
book_name VARCHAR(100),
author VARCHAR(50),
price DECIMAL(8,2),
publish_date DATE
);
INSERT INTO books VALUES
(1, 'MySQL数据库实战', '张三', 59.80, '2023-01-15'),
(2, 'Python编程从入门到精通', '李四', 79.90, '2022-11-20'),
(3, 'Java核心技术', '王五', 89.90, '2023-03-10'),
(4, 'Web前端开发实战', '李四', 69.90, '2022-09-05'),
(5, 'MySQL优化指南', '赵六', 49.90, '2023-05-20');
示例1:%通配符使用
sql
-- 查询书名包含"MySQL"的图书
SELECT
book_name AS '书名',
author AS '作者',
price AS '价格'
FROM books
WHERE book_name LIKE '%MySQL%';
-- 查询以"实战"结尾的图书
SELECT book_name
FROM books
WHERE book_name LIKE '%实战';
-- 查询以"Python"开头的图书
SELECT book_name
FROM books
WHERE book_name LIKE 'Python%';
示例2:_通配符使用
sql
-- 查询作者姓"李"且名字为两个字的图书
SELECT
book_name AS '书名',
author AS '作者'
FROM books
WHERE author LIKE '李_';
-- 查询书名第三个字是"编"的图书
SELECT book_name
FROM books
WHERE book_name LIKE '__编%';
示例3:组合使用通配符
sql
-- 查询书名以"实战"结尾且长度至少为4个字的图书
SELECT book_name
FROM books
WHERE book_name LIKE '%实战'
AND LENGTH(book_name) >= 4;
-- 查询作者不是"张"、"李"、"王"开头的图书
SELECT book_name, author
FROM books
WHERE author NOT LIKE '[张李王]%';
示例4:ESCAPE转义字符
sql
-- 当需要查询包含%或_本身时
SELECT column_name
FROM table_name
WHERE column_name LIKE '%\%%' ESCAPE '\'; -- 查找包含%的内容
SELECT column_name
FROM table_name
WHERE column_name LIKE '%\_%' ESCAPE '\'; -- 查找包含_的内容
五、用IS NULL关键字查询空值
5.1 NULL值特性说明
NULL表示"未知"或"不存在"
NULL与任何值比较都返回NULL(包括NULL本身)
不能使用 = NULL 判断,必须使用 IS NULL
5.2 实际应用示例
bash
sql
-- 示例表:客户表(customers)
CREATE TABLE customers (
customer_id INT,
customer_name VARCHAR(50),
phone VARCHAR(20),
email VARCHAR(100),
address VARCHAR(200),
register_date DATE
);
INSERT INTO customers VALUES
(1, '张三', '13800138001', 'zhangsan@email.com', '北京市朝阳区', '2023-01-15'),
(2, '李四', NULL, 'lisi@email.com', NULL, '2023-02-20'),
(3, '王五', '13900139002', NULL, '上海市浦东新区', '2023-03-10'),
(4, '赵六', NULL, NULL, NULL, '2023-04-05'),
(5, '孙七', '13700137003', 'sunqi@email.com', '广州市天河区', '2023-05-12');
示例1:查询空值
sql
-- 查询没有电话号码的客户
SELECT
customer_name AS '客户姓名',
phone AS '联系电话',
email AS '电子邮箱'
FROM customers
WHERE phone IS NULL;
查询结果:
text
客户姓名 联系电话 电子邮箱
李四 NULL lisi@email.com
赵六 NULL NULL
示例2:查询非空值
sql
-- 查询有电子邮箱的客户
SELECT
customer_name AS '客户姓名',
email AS '电子邮箱'
FROM customers
WHERE email IS NOT NULL;
示例3:多列空值判断
sql
-- 查询既没有电话也没有地址的客户
SELECT
customer_name AS '客户姓名',
register_date AS '注册日期'
FROM customers
WHERE phone IS NULL
AND address IS NULL;
5.3 空值处理函数
bash
sql
-- 使用IFNULL处理空值显示
SELECT
customer_name AS '姓名',
IFNULL(phone, '未登记') AS '联系电话',
IFNULL(address, '地址不详') AS '联系地址'
FROM customers;
-- 使用COALESCE返回第一个非空值
SELECT
customer_name,
COALESCE(email, phone, address, '无联系方式') AS '主要联系方式'
FROM customers;
六、带AND的多条件查询
6.1 基础语法格式
bash
sql
SELECT 列名 FROM 表名
WHERE 条件1 AND 条件2 AND 条件3 ...;
6.2 实际应用示例
bash
sql
-- 示例表:订单表(orders)
CREATE TABLE orders (
order_id INT,
customer_id INT,
product_name VARCHAR(100),
quantity INT,
unit_price DECIMAL(10,2),
order_date DATE,
status VARCHAR(20)
);
INSERT INTO orders VALUES
(1001, 1, '笔记本电脑', 1, 6999.00, '2023-10-15', '已完成'),
(1002, 2, '智能手机', 2, 2999.00, '2023-10-16', '待发货'),
(1003, 1, '平板电脑', 1, 3999.00, '2023-10-17', '已取消'),
(1004, 3, '无线耳机', 3, 399.00, '2023-10-18', '已完成'),
(1005, 2, '智能手表', 1, 1299.00, '2023-10-19', '待付款'),
(1006, 4, '显示器', 2, 1599.00, '2023-10-20', '待发货');
示例1:多条件组合查询
sql
-- 查询2023年10月订单金额超过5000元且状态为"已完成"的订单
SELECT
order_id AS '订单编号',
product_name AS '产品名称',
quantity AS '数量',
unit_price AS '单价',
(quantity * unit_price) AS '总金额',
order_date AS '订单日期',
status AS '订单状态'
FROM orders
WHERE order_date BETWEEN '2023-10-01' AND '2023-10-31'
AND (quantity * unit_price) > 5000
AND status = '已完成';
查询结果:
text
订单编号 产品名称 数量 单价 总金额 订单日期 订单状态
1001 笔记本电脑 1 6999.00 6999.00 2023-10-15 已完成
示例2:复杂条件组合
sql
-- 查询数量大于1且单价在1000-5000元之间的订单
SELECT
order_id,
product_name,
quantity,
unit_price,
status
FROM orders
WHERE quantity > 1
AND unit_price BETWEEN 1000 AND 5000
AND status IN ('待发货', '已完成');
示例3:结合LIKE和AND
sql
-- 查询产品名称包含"电脑"且状态不是"已取消"的订单
SELECT
order_id AS '订单号',
product_name AS '产品',
status AS '状态'
FROM orders
WHERE product_name LIKE '%电脑%'
AND status != '已取消';
6.3 注意事项
bash
sql
-- 条件执行的优先级
WHERE 条件1 OR 条件2 AND 条件3
-- 等价于:WHERE 条件1 OR (条件2 AND 条件3)
-- 建议使用括号明确优先级
WHERE (条件1 OR 条件2) AND 条件3
七、带OR的多条件查询
7.1 基础语法格式
bash
sql
SELECT 列名 FROM 表名
WHERE 条件1 OR 条件2 OR 条件3 ...;
7.2 实际应用示例
bash
sql
-- 示例表:员工考勤表(attendance)
CREATE TABLE attendance (
record_id INT,
employee_id INT,
employee_name VARCHAR(50),
department VARCHAR(30),
attendance_date DATE,
status VARCHAR(20)
);
INSERT INTO attendance VALUES
(1, 101, '张三', '技术部', '2023-10-23', '正常'),
(2, 102, '李四', '销售部', '2023-10-23', '迟到'),
(3, 103, '王五', '技术部', '2023-10-23', '请假'),
(4, 104, '赵六', '市场部', '2023-10-23', '正常'),
(5, 105, '孙七', '人事部', '2023-10-23', '早退'),
(6, 101, '张三', '技术部', '2023-10-24', '请假'),
(7, 102, '李四', '销售部', '2023-10-24', '正常');
示例1:简单OR条件查询
sql
-- 查询状态为"请假"或"迟到"的员工
SELECT
attendance_date AS '考勤日期',
employee_name AS '员工姓名',
department AS '部门',
status AS '考勤状态'
FROM attendance
WHERE status = '请假' OR status = '迟到';
查询结果:
text
考勤日期 员工姓名 部门 考勤状态
2023-10-23 李四 销售部 迟到
2023-10-23 王五 技术部 请假
2023-10-24 张三 技术部 请假
示例2:OR与IN的等价转换
sql
-- 以下两种写法等价:
SELECT * FROM attendance
WHERE status = '请假' OR status = '迟到' OR status = '早退';
SELECT * FROM attendance
WHERE status IN ('请假', '迟到', '早退');
示例3:多列OR条件查询
sql
-- 查询部门为"技术部"或状态为"正常"的记录
SELECT
attendance_date AS '日期',
employee_name AS '姓名',
department AS '部门',
status AS '状态'
FROM attendance
WHERE department = '技术部' OR status = '正常';
7.3 AND与OR的组合使用
bash
示例1:复杂条件组合
sql
-- 查询(技术部且请假)或(销售部且迟到)的员工
SELECT
employee_name AS '姓名',
department AS '部门',
status AS '状态',
attendance_date AS '日期'
FROM attendance
WHERE (department = '技术部' AND status = '请假')
OR (department = '销售部' AND status = '迟到');
示例2:多层条件嵌套
sql
-- 查询(状态为正常)或(部门为技术部且状态不为早退)的记录
SELECT *
FROM attendance
WHERE status = '正常'
OR (department = '技术部' AND status != '早退');
7.4 性能优化建议
bash
sql
-- 不推荐的写法(OR导致索引失效)
SELECT * FROM orders
WHERE customer_id = 1 OR product_name LIKE '%电脑%';
-- 推荐的改写方式(使用UNION)
SELECT * FROM orders WHERE customer_id = 1
UNION
SELECT * FROM orders WHERE product_name LIKE '%电脑%';
八、综合实战案例
8.1 复杂查询综合应用
bash
sql
-- 创建一个综合示例表
CREATE TABLE sales (
sale_id INT PRIMARY KEY,
product_id INT,
product_name VARCHAR(100),
category VARCHAR(50),
sale_date DATE,
quantity INT,
unit_price DECIMAL(10,2),
salesperson VARCHAR(50),
region VARCHAR(50)
);
-- 综合查询示例
SELECT
product_name AS '产品名称',
category AS '产品类别',
SUM(quantity) AS '总销量',
SUM(quantity * unit_price) AS '总销售额',
AVG(unit_price) AS '平均单价'
FROM sales
WHERE sale_date BETWEEN '2023-01-01' AND '2023-12-31'
AND category IN ('电子产品', '办公用品')
AND (region = '华东' OR region = '华南')
AND quantity > 0
AND salesperson IS NOT NULL
GROUP BY product_name, category
HAVING SUM(quantity * unit_price) > 10000
ORDER BY SUM(quantity * unit_price) DESC;
8.2 查询优化技巧总结
