如何高效按动态自定义作者分组统计SQL查询结果?
问题描述
现有一个简单的books表:
| author | book |
|---|---|
| Author-A | Book-A1 |
| Author-A | Book-A2 |
| Author-B | Book-B1 |
| Author-C | Book-C1 |
| Author-C | Book-C2 |
按单个作者统计书籍数量的SQL如下:
select author, count(*) from books group by author;
统计结果:
- Author-A = 2
- Author-B = 1
- Author-C = 2
但现在需要按动态自定义分组统计,例如某次分组规则为:
- groupA 包含 Author-A、Author-C
- groupB 包含 Author-B
期望得到的统计结果:
- groupA = 4
- groupB = 1
分组规则完全动态(每次请求的分组组合都可能变化),且分组数量最多可达20-30个,要求不使用UNION,求最佳SQL写法。
最佳解决方案
推荐采用分组映射表关联查询的方式,相比冗长的CASE WHEN更易维护,完美适配动态分组场景:
方法1:用VALUES构造临时映射表(适合单次动态请求)
直接在SQL中通过VALUES定义作者与分组的映射关系,再和books表关联统计:
SELECT g.group_name, COUNT(b.book) AS book_count FROM books b JOIN (VALUES ('Author-A', 'groupA'), ('Author-C', 'groupA'), ('Author-B', 'groupB') ) AS g(author, group_name) ON b.author = g.author GROUP BY g.group_name;
每次请求只需修改VALUES中的映射内容即可,无需改动SQL主体结构,20-30个分组也能清晰维护。
方法2:用CTE定义分组映射(可读性更强)
如果分组数量较多,用CTE(公共表表达式)定义映射关系,代码结构更清晰:
WITH author_groups AS ( SELECT 'Author-A' AS author, 'groupA' AS group_name UNION ALL SELECT 'Author-C' AS author, 'groupA' AS group_name UNION ALL SELECT 'Author-B' AS author, 'groupB' AS group_name ) SELECT ag.group_name, COUNT(b.book) AS book_count FROM books b JOIN author_groups ag ON b.author = ag.author GROUP BY ag.group_name;
方法3:持久化分组映射表(适合频繁复用分组)
如果分组规则需要多次复用或持久化存储,可以创建专门的映射表(如author_group_mapping),表结构如下:
| author | group_name |
|---|---|
| Author-A | groupA |
| Author-C | groupA |
| Author-B | groupB |
每次动态更新该表的映射内容后,执行以下统计SQL即可:
SELECT agm.group_name, COUNT(b.book) AS book_count FROM books b JOIN author_group_mapping agm ON b.author = agm.author GROUP BY agm.group_name;
这种方式适合需要频繁调整分组、且分组数据需要留存的场景。
内容的提问来源于stack exchange,提问作者looken-tooken
相关产品推荐
相关产品推荐

