在日常的数据管理应用中,统计和汇总重复记录的情况是经常遇到的一个问题,然后我们会根据统计结果进一步对数据进行合理化处理。比如我们有一组题库数据,主要包括题目和选项字段(如单选题目、多选题目和判断题目) ,一个合理的数据存储应该至少保证这些题目在分类中不应该出现重复题目标题数据。本文将介绍如何利用 group by 、with rollup 、having 语句来实现这一统计汇总需求,主要实现如下功能:
(1)上传 EXCEL 版试题题库到 MS SQL SERVER 数据库进行导入
(2)通过 group by 语句统计记录个数
(3)通过 group by 语句 和 with rollup 统计和汇总重复情况
(4)通过 having 子句进一步筛选出统计情况
操作系统: Windows Server 2019 DataCenter
数据库:Microsoft SQL Server 2016
.netFramework 4.7.2
假设有 EXCEL 数据题库,如图我们假设设计了错误的数据源,排序号为第207题至212题的题目列为重复值。
题库表 exams 设计如下:
序号 | 字段名 | 类型 | 说明 | 备注 |
---|---|---|---|---|
1 | sortid | int | 排序号 | 题号,唯一性 |
2 | etype | nvarchar | 试题类型 | 如多选、单选 |
3 | title | nvarchar | 题目 | |
4 | A | nvarchar | 选项A | |
5 | B | nvarchar | 选项B | |
6 | C | nvarchar | 选项C | |
7 | D | nvarchar | 选项D | |
导入功能请参阅我的文章《C#实现Excel合并单元格数据导入数据集》这里不再赘述。
首先通过 group by 按试题类型和题目进行分组统计,并使用 count、min、max 聚合函数统计题目重复的个数,出现的最小排序号和最大排序号,代码如下:
SELECT title,etype,count(title) ct,min(sortid) s1,max(sortid) s2
FROM [exams]
group by etype,Title
运行结果如下图:
使用 with ROLLUP 语句选项,如下语句:
SELECT title,etype,count(title) ct,min(sortid) s1,max(sortid) s2
FROM [exams]
group by etype,Title with ROLLUP
运行结果如下图:
如图可以看到统计中会加入汇总的记录行,NULL值,比如其中判断题共有293题,一共统计总数为654题。
前面的语句起到了统计每一个题目的和每一种题型的统计和汇总作用,我们需要对结果集进一步过滤,就需要使用 having 条件语句,写法如下:
SELECT title,etype,count(title) ct,min(sortid) s1,max(sortid) s2
FROM [exams]
group by etype,Title with ROLLUP
having count(title)>1
在查询分析器运行SQL语句,显示如下图:
如图可以看出,统计汇总结果清晰的反映出了重复记录的情况,即 count(title)>1 的 ct 字段值,值大于1 的表示该题目出现的个数。另外命令结果增加了4个行,包括单选题统计共 248 题,多选题统计共 113 题,判断题统计共 293 题,总数统计共 654 题。
我们可以继续完善对结果的分析,以标注汇总行的提示信息,可通过如下语句实现:
SELECT case when title is null then isnull(etype,'总数')+'统计情况:' else title end title
,etype,count(title) ct,min(sortid) s1,max(sortid) s2
FROM [exams]
group by etype,Title with ROLLUP
having count(title)>1
运行查询分析器,结果显示如下:
主要是通过 case when 语句对 title 字段进行判断 ,为NULL值的表示汇总行,则进行 isnull(etype,'总数')+'统计情况:' 的字符串拼接,etype字段为 NULL 值的表示总数的统计行。
更多详情请参考如下链接:
https://learn.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008-r2/ms180199(v=sql.105)
至此关于统计汇总重复记录的问题就介绍到这里,感谢您的阅读,希望本文能够对您有所帮助。