如何在WPF+SQLite中实现错误码总数及按Tool Id的动态统计?
动态生成SQL实现错误码按Tool Id透视统计
我开发了一款基于本地SQLite数据库的WPF应用,正在解析数百个文本文件提取错误数据。作为SQL新手,我需要构建查询来统计错误码的总出现次数,以及按每个Tool Id的分项统计次数。错误码与Tool Id均来自文本文件,运行时无法预知,目前我将查询结果放入WPF DataTable中展示。
数据库表结构
| 数据库ID | 批次ID | Tool Id | Error Code | 错误标题 |
|---|---|---|---|---|
| 1 | B410D9Y0 | CNP501 | 5000-503-500-BB8 | 测量错误 |
| 2 | B411DANA | CNP501 | 5000-503-500-BB8 | 测量错误 |
| 3 | B414DF40 | CNP502 | 5000-503-500-BB8 | 测量错误 |
| 4 | B414DF40 | CNP502 | 5000-503-500-BB8 | 测量错误 |
| 5 | B414DF40 | CNP502 | 5000-503-500-BB8 | 测量错误 |
| 6 | B414DFW0 | CNP502 | 1000-320-3FC-3F7 | 主序列 |
| 7 | B414DFW0 | CNP502 | 1000-0-4-0 | 因错误暂停序列 |
| 8 | B414DFW0 | CNP502 | 5000-503-500-BB8 | 测量错误 |
| 9 | B414DFW0 | CNP502 | 5000-503-500-BB8 | 测量错误 |
| 10 | B414DFW0 | CNP502 | 5000-503-500-BB8 | 测量错误 |
| 11 | B414DFW0 | CNP502 | 5000-503-500-BB8 | 测量错误 |
现有查询及结果
1. 统计错误码总出现次数
SELECT [Error Code], COUNT(*) AS Total FROM ErrorEntries GROUP BY [Error Code]
查询结果:
| Error Code | Total |
|---|---|
| 1000-0-4-0 | 1 |
| 1000-320-3FC-3F7 | 1 |
| 5000-503-500-BB8 | 9 |
2. 按Tool Id拆分统计
SELECT [Tool Id], [Error Code], COUNT(*) AS Total FROM ErrorEntries GROUP BY [Tool Id], [Error Code]
查询结果:
| Tool Id | Error Code | Total |
|---|---|---|
| CNP501 | 5000-503-500-BB8 | 2 |
| CNP502 | 1000-0-4-0 | 1 |
| CNP502 | 1000-320-3FC-3F7 | 1 |
| CNP502 | 5000-503-500-BB8 | 7 |
期望的合并统计格式
我需要将上述两个查询的结果合并,让每个Tool Id的统计数据显示在错误码总数旁,最终格式如下:
| Error Code | Total | CNP501 | CNP502 |
|---|---|---|---|
| 1000-0-4-0 | 1 | 0 | 1 |
| 1000-320-3FC-3F7 | 1 | 0 | 1 |
| 5000-503-500-BB8 | 9 | 2 | 7 |
静态透视查询实现
感谢CDnX提醒这是透视表需求,我找到了能实现该布局的静态SQL查询:
SELECT [Error Code], COUNT(*) AS Total, COUNT(CASE WHEN [Tool Id] = "CNP501" THEN 1 ELSE null end) AS CNP501, COUNT(CASE WHEN [Tool Id] = "CNP502" THEN 1 ELSE null end) AS CNP502 FROM ErrorEntries GROUP BY [Error Code] ORDER BY [Error Code];
动态生成SQL实现
由于Tool Id在运行时无法预知,我需要动态生成SQL查询。具体步骤是先从数据库中获取所有唯一的Tool Id存入字符串数组,再为每个Tool Id构建对应的COUNT语句,使用以下C#函数:
// 为每个Tool Id构建COUNT统计语句 public static string ToolErrorCountStringBuilder(string[] toolIds) { string[] toolErrorCountStrings = new string[toolIds.Length]; for (int i = 0; i < toolIds.Length; i++) { toolErrorCountStrings[i] = $"COUNT(CASE WHEN [Tool Id] = '{toolIds[i]}' THEN 1 ELSE null end) as {toolIds[i]}"; // 除最后一条语句外,其余都添加逗号 if (i != toolIds.Length - 1) { toolErrorCountStrings[i] += ","; } else { toolErrorCountStrings[i] += " "; } } return string.Join("", toolErrorCountStrings); }
随后将生成的字符串整合进完整SQL查询,填充DataTable:
public static void GetErrorCount(DataTable dt) { using (var connection = GetConnection()) { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandText = "SELECT [Error Code]," + "COUNT(*) AS Total," + ToolErrorCountStringBuilder(GetDistinctToolIds()) + "FROM ErrorEntries " + "GROUP BY [Error Code] " + "ORDER BY [Error Code]"; using (var adapter = new SQLiteDataAdapter(command)) { dt.Clear(); adapter.Fill(dt); } } } }
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

