SQL筛选条件(布尔表达式)的基础语法及多场景应用示例
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
SQL筛选条件是布尔表达式的具体应用,通过布尔表达式的真假判断来筛选数据。SQL布尔表达式是一种返回布尔值( SQL筛选条件(的定义)是用于从数据库表中筛选出符合特定规则的数据行的条件表达式,主要用在 SQL筛选条件的作用主要是缩小查询结果范围,从数据库表中精准提取符合特定要求的数据,避免返回无关信息,提高数据查询的效率和准确性。具体来说,其作用包括:
一、SQL筛选条件的语法结构SQL筛选条件的语法结构可统一表示为:
其中,条件单元可以是:
简单说明:
这个结构用在 我们来把SQL筛选条件的语法结构与SQL中布尔表达式的语法结构对比一下。 SQL中布尔表达式的语法结构可归纳为:
其中,原子条件(最基础的判断单元)包括:
简单来说,布尔表达式通过逻辑运算符(AND/OR/NOT)组合多个原子条件,最终返回 注: 二、SQL筛选条件的作用场景及位置在SQL中,筛选条件(本质是布尔表达式)常用在以下子句,各自作用场景不同:
此外,SQL筛选条件还可能出现在其他场景(如: 1、 |
示例2:多表查询中使用WHERE筛选
SELECT e.name, d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE d.location = '北京'; -- 筛选位于北京的部门的员工
语法:FROM 表1 JOIN 表2 ON 连接条件 [AND 额外筛选条件]
解析:ON
子句专门用在定义多表连接时的关联条件,在表连接过程中就对数据进行筛选,只保留符合连接条件的记录。它可以包含除了连接条件外的额外筛选条件,这些条件仅影响当前连接的表。
示例1:两表连接时使用ON筛选
SELECT e.name, p.project_name
FROM employees e
LEFT JOIN projects p
ON e.id = p.leader_id
AND p.status = '进行中'; -- 只关联状态为"进行中"的项目
示例2:ON与WHERE的区别
-- 使用ON筛选:会保留所有员工,即使没有进行中的项目
SELECT e.name, p.project_name
FROM employees e
LEFT JOIN projects p ON e.id = p.leader_id AND p.status = '进行中';
-- 使用WHERE筛选:只会保留有进行中项目的员工
SELECT e.name, p.project_name
FROM employees e
LEFT JOIN projects p ON e.id = p.leader_id
WHERE p.status = '进行中';
基础比较筛选通过比较运算符对字段值进行判断,用在数值、字符串、日期等多种数据类型,通常在WHERE
或ON
子句中使用。
语法:WHERE/ON 字段名 = 值
解析:筛选出字段值与指定值完全相等的记录,字符串需用单引号包裹,日期格式需符合数据库要求。
示例:查询职位为"工程师"的员工
SELECT id, name, position
FROM employees
WHERE position = '工程师';
输出结果:
语法:WHERE/ON 字段名 != 值
或 WHERE/ON 字段名 <> 值
解析:筛选出字段值与指定值不相等的记录,两种运算符功能完全相同。
示例:查询工资不等于5000元的员工
SELECT id, name, salary
FROM employees
WHERE salary != 5000;
输出结果:
语法:WHERE/ON 字段名 > 值
和 WHERE/ON 字段名 < 值
解析:分别筛选出字段值大于或小于指定值的记录,主要用在数值和日期类型。
示例:查询年龄大于30岁且入职时间在2023年之前的员工
SELECT id, name, age, hire_date
FROM employees
WHERE age > 30 AND hire_date < '2023-01-01';
输出结果:
语法:WHERE/ON 字段名 >= 值
和 WHERE/ON 字段名 <= 值
解析:分别筛选出字段值大于等于或小于等于指定值的记录,包含等于的情况。
示例:查询工资在4000到6000元之间的员工
SELECT id, name, salary
FROM employees
WHERE salary >= 4000 AND salary <= 6000;
输出结果:
范围筛选条件用在判断字段值是否在指定的区间内,用在需要提取某个范围内数据的场景。
语法:WHERE/ON 字段名 BETWEEN 值1 AND 值2
解析:筛选出字段值在值1和值2之间(包含边界值)的记录,等价于>= 值1 AND <= 值2
。注意值1必须小于等于值2,否则会返回空结果。
示例1:查询2023年入职的员工
SELECT id, name, hire_date
FROM employees
WHERE hire_date BETWEEN '2023-01-01' AND '2023-12-31';
输出结果:
示例2:在连接条件中使用范围筛选
SELECT o.order_id, c.name
FROM orders o
JOIN customers c ON o.customer_id = c.id
AND o.order_date BETWEEN '2023-01-01' AND '2023-06-30';
语法:WHERE/ON 字段名 NOT BETWEEN 值1 AND 值2
解析:与BETWEEN
相反,筛选出字段值不在值1和值2之间的记录,等价于< 值1 OR > 值2
。
示例:查询工资不在3000到6000元之间的员工
SELECT id, name, salary
FROM employees
WHERE salary NOT BETWEEN 3000 AND 6000;
输出结果:
集合筛选条件用在判断字段值是否属于指定的离散值集合,用在需要匹配多个可能值的场景。
语法:WHERE/ON 字段名 IN (值1, 值2, ..., 值n)
解析:筛选出字段值等于括号中任意一个值的记录,等价于多个OR
条件的组合(= 值1 OR = 值2 OR ...
)。括号中可以包含数值、字符串或子查询结果。
示例1:查询部门为研发部或市场部的员工
SELECT id, name, department
FROM employees
WHERE department IN ('研发部', '市场部');
输出结果:
示例2:在连接条件中使用IN
SELECT e.name, p.project_name
FROM employees e
JOIN projects p ON e.id = p.leader_id
AND p.priority IN ('高', '中');
语法:WHERE/ON 字段名 NOT IN (值1, 值2, ..., 值n)
解析:与IN
相反,筛选出字段值不等于括号中任何一个值的记录,等价于NOT (字段名 IN (...))
。
示例:查询既不在研发部也不在市场部的员工
SELECT id, name, department
FROM employees
WHERE department NOT IN ('研发部', '市场部');
输出结果:
模糊匹配用在对字符串类型字段进行模式匹配,用在需要根据部分字符查找记录的场景。
语法:WHERE/ON 字段名 LIKE '模式字符串'
解析:通过通配符匹配字符串的部分内容,常用通配符包括:
%
:匹配任意长度的字符串(包括空字符串)_
:匹配单个字符示例1:查询姓"张"的员工
SELECT id, name
FROM employees
WHERE name LIKE '张%';
输出结果:
示例2:查询邮箱为gmail邮箱的员工
SELECT id, name, email
FROM employees
WHERE email LIKE '%@gmail.com';
输出结果:
语法:WHERE/ON 字段名 NOT LIKE '模式字符串'
解析:与LIKE
相反,筛选出不匹配指定模式的记录。
示例:查询不是qq邮箱的员工
SELECT id, name, email
FROM employees
WHERE email NOT LIKE '%@qq.com';
语法:WHERE/ON 字段名 REGEXP '正则表达式'
解析:通过正则表达式进行复杂的模式匹配,功能比LIKE
更强大。不同数据库对正则表达式的支持略有差异。
示例:查询手机号以138开头的员工(MySQL)
SELECT id, name, phone
FROM employees
WHERE phone REGEXP '^138[0-9]{8}$';
空值(NULL)在SQL中表示未知或缺失的值,与空字符串不同,需要使用专门的运算符进行判断。
语法:WHERE/ON 字段名 IS NULL
解析:筛选出字段值为NULL的记录,不能使用= NULL
进行判断,因为NULL不等于任何值(包括自身)。
示例:查询没有填写手机号的员工
SELECT id, name, phone
FROM employees
WHERE phone IS NULL;
输出结果:
语法:WHERE/ON 字段名 IS NOT NULL
解析:筛选出字段值不为NULL的记录,即存在有效数据的记录。
示例:查询填写了邮箱地址的员工
SELECT id, name, email
FROM employees
WHERE email IS NOT NULL;
逻辑运算符用在组合多个筛选条件,实现复杂的筛选逻辑,可在WHERE
或ON
子句中使用。
语法:WHERE/ON 条件1 AND 条件2 [AND 条件3 ...]
解析:当所有条件都为真时,记录才会被选中,相当于"并且"的逻辑关系。
示例:查询研发部且工资大于6000元的员工
SELECT id, name, department, salary
FROM employees
WHERE department = '研发部' AND salary > 6000;
输出结果:
语法:WHERE/ON 条件1 OR 条件2 [OR 条件3 ...]
解析:只要有一个条件为真,记录就会被选中,相当于"或者"的逻辑关系。
示例:查询工资大于7000元或年龄小于25岁的员工
SELECT id, name, age, salary
FROM employees
WHERE salary > 7000 OR age < 25;
语法:WHERE/ON NOT 条件
解析:对条件的结果取反,即条件为假时记录被选中。
示例:查询不在人事部的员工
SELECT id, name, department
FROM employees
WHERE NOT department = '人事部';
当组合多个逻辑运算符时,使用括号()
可以改变运算优先级,明确执行顺序。
示例:查询研发部中年龄大于30岁或工资大于6000元的员工
SELECT id, name, department, age, salary
FROM employees
WHERE department = '研发部' AND (age > 30 OR salary > 6000);
子查询相关筛选条件用在根据子查询的结果进行筛选,用在需要关联多个表数据的复杂查询。
语法:WHERE EXISTS (子查询)
解析:如果子查询返回至少一行记录,则条件为真,记录被选中。EXISTS
只关注子查询是否有结果,不关心具体内容。
示例:查询有订单记录的客户
SELECT id, name
FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);
语法:WHERE NOT EXISTS (子查询)
解析:与EXISTS
相反,如果子查询没有返回任何记录,则条件为真。
示例:查询没有订单记录的客户
SELECT id, name
FROM customers c
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);
语法:WHERE 字段名 比较运算符 ALL (子查询)
解析:字段值与子查询返回的所有值比较,当所有比较都为真时,条件为真。
示例:查询工资高于所有实习生工资的正式员工
SELECT id, name, salary
FROM employees
WHERE position = '正式员工'
AND salary > ALL (SELECT salary FROM employees WHERE position = '实习生');
语法:WHERE 字段名 比较运算符 ANY (子查询)
解析:字段值与子查询返回的任何一个值比较,只要有一个比较为真,条件就为真。
示例:查询工资高于至少一个实习生工资的正式员工
SELECT id, name, salary
FROM employees
WHERE position = '正式员工'
AND salary > ANY (SELECT salary FROM employees WHERE position = '实习生');
分组筛选条件用在对分组后的结果进行筛选,与GROUP BY
子句配合使用。
语法:GROUP BY 字段名 HAVING 分组条件
解析:HAVING
子句用在筛选分组后的结果,类似于WHERE
但作用于分组。WHERE
在分组前筛选记录,HAVING
在分组后筛选组。
示例1:查询员工人数超过2人的部门
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 2;
输出结果:
示例2:查询平均工资大于5000元的部门
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 5000;
条件表达式允许在筛选中使用复杂的条件判断逻辑,实现动态的筛选规则。
语法:
WHERE CASE
WHEN 条件1 THEN 结果1
WHEN 条件2 THEN 结果2
...
ELSE 结果N
END 比较运算符 值
解析:CASE WHEN
用在创建条件表达式,根据不同条件返回不同结果,然后可以与其他值进行比较。
示例:查询成年员工(18-60岁)
SELECT id, name, age
FROM employees
WHERE CASE
WHEN age >= 18 AND age <= 60 THEN '成年'
ELSE '非成年'
END = '成年';
SQL提供了一些特殊函数,可用在实现特定的筛选需求。
语法:WHERE 字段名 > GREATEST(值1, 值2, ...)
解析:GREATEST
返回参数中的最大值,可用在比较字段值是否大于多个值中的最大值。
示例:查询工资高于3000、4000、5000中最大值的员工
SELECT id, name, salary
FROM employees
WHERE salary > GREATEST(3000, 4000, 5000);
语法:WHERE 字段名 < LEAST(值1, 值2, ...)
解析:LEAST
返回参数中的最小值,可用在比较字段值是否小于多个值中的最小值。
示例:查询工资低于5000、6000、7000中最小值的员工
SELECT id, name, salary
FROM employees
WHERE salary < LEAST(5000, 6000, 7000);
WHERE
ON
WHERE
ON
用在连接条件=
>
, <
, >=
, <=
BETWEEN...AND...
IN
NOT IN
LIKE
REGEXP
IS NULL
IS NOT NULL
AND
OR
, NOT
EXISTS
ALL
, ANY
HAVING
CASE WHEN
GREATEST
LEAST
窗口函数(Window Function)能在不聚合数据的前提下,对“组内数据”进行排序、排名或计算,结合筛选条件可实现“组内Top N”、“前后对比”等高级需求。
用ROW_NUMBER()
给每组数据编号,再筛选编号≤N的记录(用在按类别取前几名)。
语法:
WITH 临时表名 AS (
SELECT
字段列表,
ROW_NUMBER() OVER (PARTITION BY 分组字段 ORDER BY 排序字段 DESC) AS 组内序号
FROM 表名
)
SELECT * FROM 临时表名 WHERE 组内序号 <= N;
解析:
PARTITION BY
:按指定字段分组(如按“部门”分组)ORDER BY
:组内排序(如按“工资”降序)ROW_NUMBER()
:每组内生成唯一序号(1,2,3...,相同值也会按顺序编号)RANK()
(相同值同序号,后续序号跳跃)或DENSE_RANK()
(相同值同序号,后续序号连续)示例:查询每个部门工资最高的2名员工
WITH dept_salary AS (
SELECT
id, name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
FROM employees
)
SELECT id, name, department, salary
FROM dept_salary
WHERE rn <= 2; -- 取每组前2名
输出结果(示例):
用LAG()
(取前N行数据)或LEAD()
(取后N行数据)获取“相邻记录”,再通过对比实现“连续增长/下降”、“前后差异”等筛选。
语法:
WITH 临时表名 AS (
SELECT
字段列表,
LAG(对比字段, N) OVER (ORDER BY 排序字段) AS 前N行值, -- N默认为1
LEAD(对比字段, N) OVER (ORDER BY 排序字段) AS 后N行值
FROM 表名
)
SELECT * FROM 临时表名 WHERE 对比条件; -- 如:当前值 > 前1行值(连续增长)
示例:查询连续两个月销售额增长的月份(假设sales
表有month
、amount
字段)
WITH sales_trend AS (
SELECT
month,
amount,
LAG(amount) OVER (ORDER BY month) AS last_month_amount -- 取上月销售额
FROM sales
)
SELECT month, amount, last_month_amount
FROM sales_trend
WHERE amount > last_month_amount; -- 本月 > 上月(增长)
输出结果:
递归CTE(Common Table Expression,公用表表达式)用在处理“层级数据”(如:部门树、评论回复、地区层级),可实现“查询某节点的所有子节点”、“查询某节点的所有父节点”等筛选。
通过“初始条件(根节点)+ 递归条件(子节点关联父节点)”遍历所有子节点。
语法:
WITH RECURSIVE 递归表名 AS (
-- 1. 初始查询:定位根节点(需要筛选的起始节点)
SELECT * FROM 表名 WHERE 根节点条件
UNION ALL
-- 2. 递归查询:关联子节点(子节点的父ID = 上一层的ID)
SELECT 子.* FROM 表名 子
INNER JOIN 递归表名 父 ON 子.父ID字段 = 父.ID字段
)
SELECT * FROM 递归表名; -- 结果包含根节点及所有子节点
示例:查询“研发部”(ID=1)的所有下属部门(假设departments
表有id
、name
、parent_id
字段)
WITH RECURSIVE dept_tree AS (
-- 初始:找到研发部(根节点)
SELECT id, name, parent_id
FROM departments
WHERE id = 1 -- 研发部ID=1
UNION ALL
-- 递归:找到所有子部门(parent_id = 上一层的id)
SELECT d.id, d.name, d.parent_id
FROM departments d
INNER JOIN dept_tree dt ON d.parent_id = dt.id
)
SELECT * FROM dept_tree;
输出结果(示例):
从子节点出发,递归查询父节点,直到根节点(parent_id为NULL)。
示例:查询“测试小组”(ID=4)的所有上级部门
WITH RECURSIVE dept_parents AS (
-- 初始:找到测试小组(子节点)
SELECT id, name, parent_id
FROM departments
WHERE id = 4
UNION ALL
-- 递归:找到父部门(父部门的id = 上一层的parent_id)
SELECT d.id, d.name, d.parent_id
FROM departments d
INNER JOIN dept_parents dp ON d.id = dp.parent_id
)
SELECT * FROM dept_parents;
输出结果:
基础LIKE
只能处理简单模糊匹配,而正则表达式(REGEXP
/RLIKE
)支持“捕获组”、“零宽断言”、“重复模式”等高级语法,可筛选符合复杂格式的数据(如手机号、邮箱、身份证号的严格校验)。
语法:WHERE 字段名 REGEXP '正则模式'
(注:不同数据库正则语法略有差异,以下以MySQL为例)
示例:筛选18位身份证号(前6位地址码,8位生日,3位顺序码,1位校验码)
SELECT id, name, id_card
FROM users
WHERE id_card REGEXP '^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$';
正则解析:
^[1-9]\\d{5}
:前6位(非0开头,共6位)(19|20)\\d{2}
:年份(19xx或20xx)(0[1-9]|1[0-2])
:月份(01-12)(0[1-9]|[12]\\d|3[01])
:日期(01-31)\\d{3}[0-9Xx]
:最后4位(3位顺序码+1位校验码,校验码可为X/x)结合REGEXP_SUBSTR
(提取匹配的子串),可先从字段中提取特定内容,再筛选。
示例:从日志中筛选“ERROR”级别的记录,并提取错误时间
SELECT
log_id,
-- 从日志内容中提取时间(格式:[2023-10-01 12:30:00])
REGEXP_SUBSTR(log_content, '\\[\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\]') AS error_time
FROM logs
WHERE log_content REGEXP 'ERROR'; -- 先筛选包含ERROR的日志
现代数据库(如MySQL 5.7+、PostgreSQL、SQL Server)支持JSON类型字段,可通过JSON函数直接筛选JSON中的数据,无需解析为结构化字段。
语法(以MySQL为例):
JSON_EXTRACT(json字段, '$.键名')
:提取JSON中指定键的值json字段->'$.键名'
(提取为字符串)、json字段->>'$.键名'
(提取为原生类型)示例:筛选“用户标签”中包含“VIP”的用户(假设users
表有tags
字段,存储JSON:{"level":"VIP", "interest":["sports","music"]}
)
SELECT id, name, tags
FROM users
WHERE tags->>'$.level' = 'VIP'; -- 提取level字段,筛选值为VIP的用户
示例:筛选“兴趣标签”包含“music”的用户(JSON数组匹配)
SELECT id, name, tags
FROM users
WHERE JSON_CONTAINS(tags->'$.interest', '"music"'); -- 检查数组是否包含"music"
解析:JSON_CONTAINS(json数组, 目标值)
:判断JSON数组是否包含指定元素(注意目标值需用双引号包裹,如"music"
)
支持空间数据的数据库(如PostgreSQL+PostGIS、MySQL 8.0+)可通过空间函数筛选“地理位置相关”的数据(如“某区域内的店铺”“距离某点5公里内的用户”)。
语法(以PostgreSQL+PostGIS为例):
ST_DWithin(点1, 点2, 距离)
:判断两点距离是否小于等于指定值(单位:米)示例:筛选“东方明珠(经纬度:121.499588, 31.239752)”周边3公里内的店铺
SELECT id, name, address
FROM shops
WHERE ST_DWithin(
shops.location, -- 店铺位置(geometry类型)
ST_SetSRID(ST_MakePoint(121.499588, 31.239752), 4326), -- 东方明珠坐标(转换为地理坐标)
3000 -- 距离3000米(3公里)
);
解析:
ST_MakePoint(经度, 纬度)
:创建点坐标ST_SetSRID(..., 4326)
:指定坐标系(4326为WGS84,即GPS坐标系)ST_DWithin
:判断两点距离是否在指定范围内示例:筛选“某商圈多边形范围内”的店铺
SELECT id, name
FROM shops
WHERE ST_Within(
shops.location,
-- 多边形坐标(按顺序定义顶点,闭合多边形)
ST_PolygonFromText('POLYGON((116.3 39.9, 116.4 39.9, 116.4 40.0, 116.3 40.0, 116.3 39.9))', 4326)
);
解析:ST_Within(点, 多边形)
:判断点是否在多边形内部
当筛选条件不固定(如用户可动态选择筛选维度),可通过“参数化查询”或“条件拼接”实现动态逻辑,避免硬编码。
示例(MySQL存储过程):根据输入参数动态筛选员工
CREATE PROCEDURE get_employees(
IN p_department VARCHAR(50), -- 部门参数(可为NULL,表示不筛选)
IN p_min_salary DECIMAL(10,2) -- 最低薪资参数(可为NULL,表示不筛选)
)
BEGIN
SELECT id, name, department, salary
FROM employees
WHERE
(p_department IS NULL OR department = p_department) -- 若参数为NULL,则忽略该条件
AND (p_min_salary IS NULL OR salary >= p_min_salary);
END;
调用示例:
CALL get_employees('研发部', 5000);
CALL get_employees(NULL, 6000);
示例:根据“用户类型”动态切换筛选规则(VIP用户查近30天数据,普通用户查近7天)
SELECT id, user_id, order_time
FROM orders
WHERE order_time >= CASE
WHEN (SELECT user_type FROM users WHERE id = orders.user_id) = 'VIP'
THEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) -- VIP:近30天
ELSE DATE_SUB(CURDATE(), INTERVAL 7 DAY) -- 普通用户:近7天
END;
通过“聚合函数+窗口函数”的嵌套,可实现“累计值筛选”、“占比筛选”等高级统计筛选(如:“累计销售额达100万的日期”“某产品销量占比超20%的区域”)。
示例:查询2023年累计销售额首次突破100万的日期
WITH sales_cumulative AS (
SELECT
sale_date,
amount,
-- 累计销售额(按日期排序,累加金额)
SUM(amount) OVER (ORDER BY sale_date) AS cum_amount
FROM sales
WHERE YEAR(sale_date) = 2023
)
SELECT sale_date, cum_amount
FROM sales_cumulative
WHERE cum_amount >= 1000000 -- 累计达标
ORDER BY sale_date
LIMIT 1; -- 取首次达标的日期
示例:筛选“销量占比超过20%”的产品类别
WITH category_sales AS (
SELECT
category,
SUM(amount) AS cat_amount,
-- 总销售额(所有类别的总和)
SUM(SUM(amount)) OVER () AS total_amount
FROM products
GROUP BY category
)
SELECT category, cat_amount, (cat_amount/total_amount)*100 AS ratio
FROM category_sales
WHERE (cat_amount/total_amount) > 0.2; -- 占比超20%
复杂筛选场景中,直接使用子查询可能效率较低,通过“子查询改写为JOIN”“提前过滤”等技巧可提升性能,同时实现同等筛选效果。
原查询(关联子查询,可能多次执行):
-- 筛选有订单的用户(关联子查询)
SELECT id, name
FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.status = 'paid');
改写为JOIN(更高效):
SELECT DISTINCT u.id, u.name -- DISTINCT去重(避免用户多条订单导致重复)
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.status = 'paid'; -- 提前筛选已支付订单,减少关联数据量
在子查询或JOIN前先筛选数据,减少后续处理的数据量(尤其用在大表)。
示例:查询“2023年销售额最高的部门”(先筛选2023年数据,再聚合)
-- 先筛选2023年数据,再计算部门销售额(比全表聚合更高效)
WITH 2023_sales AS (
SELECT department, amount
FROM sales
WHERE sale_date BETWEEN '2023-01-01' AND '2023-12-31'
)
SELECT department, SUM(amount) AS total
FROM 2023_sales
GROUP BY department
ORDER BY total DESC
LIMIT 1;
到这儿,SQL筛选条件拆解结束。懂了这知识,我们就可以运用SQL筛选条件帮我们从一堆数据里挑出我们想要的。不管是简单找个符合条件的行,还是复杂的分组筛选、多表关联挑数据,都是用布尔表达式判断 “要不要这条”。掌握好这些SQL筛选条件,查数据就能又快又准,不用在一堆无关数据里翻哈。
阅读原文:原文链接