Sql根据不同条件统计总数

前言

经常会遇到根据不同的条件统计总数的问题,一般有两种写法:count和sum都可以
数据准备:
在这里插入图片描述

方法一 :Count

代码:

SELECT
	COUNT(
		CASE
		WHEN age > 20
		AND age < 25 THEN
			1
		ELSE
			NULL
		END
	) AS cnt0,
	COUNT(
		CASE
		WHEN age >= 25
		AND age < 30 THEN
			1
		ELSE
			NULL
		END
	) AS cnt1
FROM
	USER;

结果:
在这里插入图片描述

方法二:sum

代码:

SELECT
	SUM(
		CASE
		WHEN age > 20
		AND age < 25 THEN
			1
		ELSE
			0
		END
	) AS cnt0,
	SUM(
		CASE
		WHEN age >= 25
		AND age < 30 THEN
			1
		ELSE
			0
		END
	) AS cnt1
FROM
	USER;

结果:
在这里插入图片描述
当然也可以和count代码一样ELSE后面也写为NULL

SELECT
	SUM(
		CASE
		WHEN age > 20
		AND age < 25 THEN
			1
		ELSE
			NULL
		END
	) AS cnt0,
	SUM(
		CASE
		WHEN age >= 25
		AND age < 30 THEN
			1
		ELSE
			NULL
		END
	) AS cnt1
FROM
	USER;

后记

其实原理很简单,count统计的时候有满足条件的就加1,没有满足的变为NULL,我们知道聚合函数统计的时候是忽略null值的;而sum原理和coun相似,不过ELSE后面可以是0或者NULL。

<think>首先,用户的问题是关于SQL的:他们想使用SQL根据特定条件统计记录数量,特别是关于COUNT语句和WHERE条件的使用案例。我需要基于提供的引用来构建回答。 关键点: - 用户的问题:SQL COUNT语句 WHERE条件的使用案例。 - 系统指令:回答必须使用中文,结构清晰,帮助用户逐步解决问题。确保回答真实可靠。 - 引用内容:提供了几个相关的SQL例子,涉及WHERE条件、聚合函数的使用、COUNT条件计数等。 回顾引用: - 引用[1]:展示了WHERE条件中使用数组形式,特别是用exp表达式来处理IS NOT NULL。 - 引用[2]:解释了WHERE子句中不能直接使用聚合函数如COUNT,因为聚合函数应在GROUP BY之后使用,推荐使用HAVING子句。 - 引用[3]:讨论了COUNT函数中条件计数的技巧,如使用OR NULL来确保只计数满足条件的记录。 - 引用[4]:展示了WHERE条件中的复杂判断,包括日期格式化和字符串操作。 用户需求:他们想根据特定条件统计记录数量,所以需要解释如何使用COUNT与WHERE。 结构化回答: 1. **介绍基本概念**:解释COUNT函数的作用,以及WHERE子句用于过滤记录。 2. **使用案例**:提供具体的SQL例子,展示如何结合COUNT和WHERE。 3. **注意事项**:基于引用,强调WHERE子句中不能直接使用聚合函数,需要使用HAVING或条件技巧。 4. **常见错误和解决方案**:引用用户可能遇到的错误,如无效使用聚合函数。 5. **相关优化或高级用法**:如果适用,添加一些优化技巧。 确保回答清晰: - 使用标题或分段。 - 提供代码示例。 - 自然地添加引用标识。 最终,生成相关问题,如系统指令要求。 大纲回答: 1. **引言**:简要解释COUNT和WHERE的使用。 2. **基本用法**:简单COUNT与WHERE的例子。 3. **条件计数**:如何计数满足特定条件的记录,使用CASE或OR NULL技巧。 4. **聚合函数的限制**:解释为什么WHERE中不能有聚合函数,并提供替代方案(GROUP BY + HAVING)。 5. **示例代码**:基于引用,提供实际SQL语句。 6. **总结**:关键点回顾。 7. **相关问题**:生成2-3个相关问题。 代码格式:使用代码块包裹SQL语句。 引用来源:在相关部分末尾添加引用标识,如[^1], [^2]等。</think>### SQL COUNT语句与WHERE条件使用指南 在SQL中,`COUNT()`函数用于统计记录数量,而`WHERE`子句用于过滤记录。结合使用时,您可以根据特定条件高效地统计数据。以下是基于实际案例的详细解释和示例,帮助您逐步掌握用法。回答参考了SQL标准语法和常见实践[^2][^3]。 --- ### 一、基本用法:COUNT与WHERE结合 `COUNT()`函数统计满足`WHERE`条件的记录数。基本语法为: ```sql SELECT COUNT(column_name) FROM table_name WHERE condition; ``` - **`COUNT(*)`**:统计所有记录(包括NULL值)。 - **`COUNT(column_name)`**:统计指定列的非NULL值。 - `WHERE`条件用于筛选记录,例如等于、不等于、范围等。 #### 示例案例 假设有一个`users`表,包含`id`、`name`、`status`(状态:0表示未激活,1表示激活)和`phone`(手机号,可能为NULL)字段。 **需求:统计激活用户(status=1)的数量。** ```sql SELECT COUNT(*) AS active_users FROM users WHERE status = 1; ``` 结果:返回`active_users`列,显示status=1的记录总数。 **关键点**: - `WHERE`条件先过滤记录,`COUNT()`再统计过滤后的结果。 - 适用于简单条件(如等值比较、IS NOT NULL)。 --- ### 二、高级用法:条件计数与复杂WHERE 当需要基于复杂条件统计时(如计数满足特定逻辑的记录),可使用`CASE`表达式或`OR NULL`技巧。`WHERE`子句本身不能直接包含聚合函数(如`COUNT`),否则会报错"Invalid use of group function"[^2][^3]。 #### 1. **条件计数:使用CASE表达式** **需求:统计手机号不为空且状态激活的用户数量。** ```sql SELECT COUNT(CASE WHEN phone IS NOT NULL AND status = 1 THEN 1 END) AS valid_users FROM users; ``` - **解释**:`CASE`在`COUNT`内部定义条件,仅当`phone`非空且`status=1`时计数。 - **优点**:避免`WHERE`限制,支持多条件组合。 #### 2. **OR NULL技巧:避免错误计数** **需求:统计phone列值大于0的记录数量(phone可能为NULL或负数)。** 错误写法:`COUNT(phone > 0)`会统计所有记录(包括不满足条件的),因为`phone > 0`返回布尔值而非NULL。 正确写法: ```sql SELECT COUNT(phone > 0 OR NULL) AS positive_phones FROM users; ``` - **解释**:`OR NULL`确保当条件不满足时返回NULL,`COUNT()`忽略NULL值,从而正确计数[^3]。 - **适用场景**:需要内联条件判断时。 #### 3. **WHERE中使用IS NOT NULL** **需求:统计phone列非空的记录数量(参考引用[1]的exp表达式)。** ```sql SELECT COUNT(*) FROM users WHERE phone IS NOT NULL; ``` - 在框架如ThinkPHP中,可用数组形式简化: ```php $where = array('phone' => array('exp', 'IS NOT NULL')); $count = M('users')->where($where)->count(); ``` --- ### 三、WHERE中聚合函数的限制与解决方案 `WHERE`子句在分组前过滤记录,不能直接包含聚合函数(如`COUNT`, `SUM`)。否则会报错"Invalid use of group function"[^2]。 **解决方案**:使用`GROUP BY`和`HAVING`子句。 #### 示例案例 **需求:统计name列重复的记录数量(如出现次数>1)。** 错误写法: ```sql SELECT name FROM users WHERE COUNT(name) > 1; -- 报错! ``` 正确写法: ```sql SELECT name, COUNT(name) AS count FROM users GROUP BY name HAVING COUNT(name) > 1; ``` - **解释**: - `GROUP BY name`:按name分组。 - `HAVING COUNT(name) > 1`:过滤分组后计数大于1的组。 - **与WHERE的区别**: - `WHERE`:过滤单个记录(如`status=1`)。 - `HAVING`:过滤分组结果(如`COUNT(name) > 1`)[^2]。 --- ### 四、综合案例:日期条件与字符串操作 参考引用[4],结合日期和字符串条件统计记录。 **需求:统计某能源表(t_meter_s)中,当前日期匹配且eneid前缀符合条件的记录数量。** ```sql SELECT COUNT(*) AS total FROM t_meter_s WHERE SUBSTRING(eneid, 1, LENGTH('{prefix}')) = '{prefix}' -- eneid前缀匹配 AND enetype = '${enetype}' -- 类型匹配 AND ( (enetype = '01' AND DATE_FORMAT(time, '%y-%m%d') = DATE_FORMAT(NOW(), '%y-%m%d')) OR -- 日类型 (enetype = '10' AND DATE_FORMAT(time, '%y-%m') = DATE_FORMAT(NOW(), '%y-%m')) OR -- 月类型 (enetype = '11' AND DATE_FORMAT(time, '%y') = DATE_FORMAT(NOW(), '%y')) -- 年类型 ); ``` - **关键点**:`WHERE`支持复杂逻辑(如`OR`组合和函数计算),但确保条件不包含聚合函数。 --- ### 五、最佳实践总结 1. **优先使用WHERE过滤**:在`COUNT()`前用`WHERE`缩小数据集,提升性能。 2. **聚合函数位置**: - 简单条件:直接用`WHERE`(如`status=1`)。 - 分组条件:用`GROUP BY` + `HAVING`(如重复值统计)。 - 内联条件:用`CASE`或`OR NULL`[^3]。 3. **避免常见错误**: - 不在`WHERE`中使用聚合函数。 - 处理NULL值时,明确使用`IS NULL`或`IS NOT NULL`。 通过以上案例,您可以灵活应用`COUNT`和`WHERE`解决大多数统计需求。如需进一步优化,可考虑索引或查询重构。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunnyRivers

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值