求SQL查询语句:统计各用户FormIds数量并生成用户总数与总FormIds数
分号分隔字段计数及汇总SQL实现
问题背景
现有数据表结构如下:
| Id | Name | FormIds |
|---|---|---|
| 1 | john.doe@blah.co | 32132;32323;232323;424323;2323;23232;2323 |
| 2 | jane.doe@whatever.co | 32323;11123;11321 |
| 3 | joe.blow@yeet.co | 22324 |
需要编写SQL查询,返回每个用户对应的分号分隔FormIds条目数量,并在最后一行汇总总用户数和所有FormIds的总数量,期望输出如下:
| 用户名 | 单用户FormIds数量 |
|---|---|
| john.doe@blah.co | 7 |
| jane.doe@whatever.co | 3 |
| joe.blow@yeet.co | 1 |
| ----------------------- | ------------------- |
| 3 | 11 |
解决方案
MySQL 版本
通过计算分号数量统计条目数,再拼接汇总行:
-- 查询每个用户的FormIds数量 SELECT Name AS 用户名, CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE LENGTH(FormIds) - LENGTH(REPLACE(FormIds, ';', '')) + 1 END AS 单用户FormIds数量 FROM 你的表名 UNION ALL -- 汇总总用户数和总FormIds数 SELECT CAST(COUNT(*) AS CHAR) AS 用户名, SUM( CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE LENGTH(FormIds) - LENGTH(REPLACE(FormIds, ';', '')) + 1 END ) AS 单用户FormIds数量 FROM 你的表名;
SQL Server 版本
使用LEN()函数替换计数,逻辑与MySQL一致:
SELECT Name AS 用户名, CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE LEN(FormIds) - LEN(REPLACE(FormIds, ';', '')) + 1 END AS 单用户FormIds数量 FROM 你的表名 UNION ALL SELECT CAST(COUNT(*) AS VARCHAR(10)) AS 用户名, SUM( CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE LEN(FormIds) - LEN(REPLACE(FormIds, ';', '')) + 1 END ) AS 单用户FormIds数量 FROM 你的表名;
PostgreSQL 版本
提供两种实现方式,任选其一:
方法1:数组长度法
SELECT Name AS 用户名, CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE ARRAY_LENGTH(STRING_TO_ARRAY(FormIds, ';'), 1) END AS 单用户FormIds数量 FROM 你的表名 UNION ALL SELECT CAST(COUNT(*) AS TEXT) AS 用户名, SUM( CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE ARRAY_LENGTH(STRING_TO_ARRAY(FormIds, ';'), 1) END ) AS 单用户FormIds数量 FROM 你的表名;
方法2:替换计数法
SELECT Name AS 用户名, CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE CHAR_LENGTH(FormIds) - CHAR_LENGTH(REPLACE(FormIds, ';', '')) + 1 END AS 单用户FormIds数量 FROM 你的表名 UNION ALL SELECT CAST(COUNT(*) AS TEXT) AS 用户名, SUM( CASE WHEN FormIds IS NULL OR FormIds = '' THEN 0 ELSE CHAR_LENGTH(FormIds) - CHAR_LENGTH(REPLACE(FormIds, ';', '')) + 1 END ) AS 单用户FormIds数量 FROM 你的表名;
关键说明
- 空值处理:针对
FormIds为空或NULL的情况,返回0条,避免计算错误; - 汇总行:用
UNION ALL合并明细和汇总数据,注意字段类型统一(将数字转为字符串); - 核心逻辑:分号数量比条目数少1,通过字符串长度差计算分号数量,加1得到条目总数。
内容的提问来源于stack exchange,提问作者bigjimcfh
相关产品推荐
相关产品推荐

