C# Winform 使用SUM CASE WHEN实现动态列交叉数据报表
C# Winform 使用SUM CASE WHEN实现动态列交叉数据报表
使用SUM CASE WHEN实现动态列交叉报表
a) 根据查询条件返回不同字段的结果数据。
b) 根据查询条件自动创建表格的列。
1. 按年度生成动态列的SQL脚本
SQL Code:
SELECT Account,OperationType,
SUM(CASE WHEN YEAR(OperationTime)=2015 THEN 1 ELSE 0 END) AS Y2015,
SUM(CASE WHEN YEAR(OperationTime)= 2016 THEN 1 ELSE 0 END) AS Y2016,
SUM(CASE WHEN YEAR(OperationTime)= 2017 THEN 1 ELSE 0 END) AS Y2017,
SUM(CASE WHEN YEAR(OperationTime)= 2018 THEN 1 ELSE 0 END) AS Y2018,
SUM(CASE WHEN YEAR(OperationTime)= 2019 THEN 1 ELSE 0 END) AS Y2019,
SUM(CASE WHEN YEAR(OperationTime)= 2020 THEN 1 ELSE 0 END) AS Y2020,
SUM(CASE WHEN YEAR(OperationTime)= 2021 THEN 1 ELSE 0 END) AS Y2021
FROM sys_LogOperation
GROUP BY Account,OperationType;
//来源:C/S框架网 | www.csframework.com | QQ:23404761
SUM(CASE WHEN YEAR(OperationTime)=2015 THEN 1 ELSE 0 END) AS Y2015,
SUM(CASE WHEN YEAR(OperationTime)= 2016 THEN 1 ELSE 0 END) AS Y2016,
SUM(CASE WHEN YEAR(OperationTime)= 2017 THEN 1 ELSE 0 END) AS Y2017,
SUM(CASE WHEN YEAR(OperationTime)= 2018 THEN 1 ELSE 0 END) AS Y2018,
SUM(CASE WHEN YEAR(OperationTime)= 2019 THEN 1 ELSE 0 END) AS Y2019,
SUM(CASE WHEN YEAR(OperationTime)= 2020 THEN 1 ELSE 0 END) AS Y2020,
SUM(CASE WHEN YEAR(OperationTime)= 2021 THEN 1 ELSE 0 END) AS Y2021
FROM sys_LogOperation
GROUP BY Account,OperationType;
//来源:C/S框架网 | www.csframework.com | QQ:23404761
2. 按固定项目生成动态列的SQL脚本
SQL Code:
SELECT YEAR(OperationTime) AS YearItem,
SUM(CASE WHEN OperationType = 'OpenForm' THEN 1 ELSE 0 END) AS OpenForm,
SUM(CASE WHEN OperationType = 'Exception' THEN 1 ELSE 0 END) AS Exception,
SUM(CASE WHEN OperationType = 'CustomError' THEN 1 ELSE 0 END) AS CustomError
FROM sys_LogOperation
GROUP BY YEAR(OperationTime);
//来源:C/S框架网 | www.csframework.com | QQ:23404761
SUM(CASE WHEN OperationType = 'OpenForm' THEN 1 ELSE 0 END) AS OpenForm,
SUM(CASE WHEN OperationType = 'Exception' THEN 1 ELSE 0 END) AS Exception,
SUM(CASE WHEN OperationType = 'CustomError' THEN 1 ELSE 0 END) AS CustomError
FROM sys_LogOperation
GROUP BY YEAR(OperationTime);
//来源:C/S框架网 | www.csframework.com | QQ:23404761
3. 界面设计参考

4. 查询结果,动态创建列

C# Code:
/// <summary>
/// 动态窗体GridColumn实例
/// </summary>
/// <param name="years"></param>
private void CreateDynamicColumns(string[] years)
{
//清除所有列
gridView1.Columns.Clear();
//添加默认列OperationType,Account,左侧固定
gridView1.Columns.Add(colAccount);
gridView1.Columns.Add(colType);
colAccount.VisibleIndex = 0;
colType.VisibleIndex = 1;
int v = 2;
foreach (var year in years)
{
GridColumn col = new GridColumn();
col.Name = "col" + year;
col.Caption = year;
col.FieldName = "Y" + year;//字段名
col.Width = 100;
col.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum;//数字合计
col.VisibleIndex = v;
col.Visible = true;
gridView1.Columns.Add(col);
v++;
}
}
//来源:C/S框架网 | www.csframework.com | QQ:23404761
/// <summary>
/// 动态窗体GridColumn实例
/// </summary>
/// <param name="years"></param>
private void CreateDynamicColumns(string[] years)
{
//清除所有列
gridView1.Columns.Clear();
//添加默认列OperationType,Account,左侧固定
gridView1.Columns.Add(colAccount);
gridView1.Columns.Add(colType);
colAccount.VisibleIndex = 0;
colType.VisibleIndex = 1;
int v = 2;
foreach (var year in years)
{
GridColumn col = new GridColumn();
col.Name = "col" + year;
col.Caption = year;
col.FieldName = "Y" + year;//字段名
col.Width = 100;
col.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum;//数字合计
col.VisibleIndex = v;
col.Visible = true;
gridView1.Columns.Add(col);
v++;
}
}
//来源:C/S框架网 | www.csframework.com | QQ:23404761
5. 演示界面源码位置
CSFrameworkV5-ClientFoundation
\CSFrameworkV5.Report.frmDynamicReport

6. DAL层源码
C# Code:
public DataSet GetDynamicReport(string[] years)
{
//组合SQL1
StringBuilder sb = new StringBuilder();
sb.AppendLine($"SELECT Account,OperationType, ");
for (int i = 0; i <= years.Length - 1; i++)
{
string year = years[i].Trim();//必须去空格!
string item = $" SUM(CASE WHEN YEAR(OperationTime)={year} THEN 1 ELSE 0 END) AS Y{year} ";
if (i < years.Length - 1) item += ", ";
sb.AppendLine(item);
}
sb.AppendLine("FROM sys_LogOperation ");
sb.AppendLine("GROUP BY Account,OperationType; ");
string sql1 = sb.ToString();
//组合SQL2
string sql2 = "SELECT YEAR(OperationTime) AS YearItem, " +
" SUM(CASE WHEN OperationType = 'OpenForm' THEN 1 ELSE 0 END) AS OpenForm, " +
" SUM(CASE WHEN OperationType = 'Exception' THEN 1 ELSE 0 END) AS Exception, " +
" SUM(CASE WHEN OperationType = 'CustomError' THEN 1 ELSE 0 END) AS CustomError " +
"FROM sys_LogOperation " +
"GROUP BY YEAR(OperationTime); ";
DataSet ds = DatabaseProvider.SystemDatabase.GetDataSet(sql1 + sql2);
return ds;
}
//来源:C/S框架网 | www.csframework.com | QQ:23404761
public DataSet GetDynamicReport(string[] years)
{
//组合SQL1
StringBuilder sb = new StringBuilder();
sb.AppendLine($"SELECT Account,OperationType, ");
for (int i = 0; i <= years.Length - 1; i++)
{
string year = years[i].Trim();//必须去空格!
string item = $" SUM(CASE WHEN YEAR(OperationTime)={year} THEN 1 ELSE 0 END) AS Y{year} ";
if (i < years.Length - 1) item += ", ";
sb.AppendLine(item);
}
sb.AppendLine("FROM sys_LogOperation ");
sb.AppendLine("GROUP BY Account,OperationType; ");
string sql1 = sb.ToString();
//组合SQL2
string sql2 = "SELECT YEAR(OperationTime) AS YearItem, " +
" SUM(CASE WHEN OperationType = 'OpenForm' THEN 1 ELSE 0 END) AS OpenForm, " +
" SUM(CASE WHEN OperationType = 'Exception' THEN 1 ELSE 0 END) AS Exception, " +
" SUM(CASE WHEN OperationType = 'CustomError' THEN 1 ELSE 0 END) AS CustomError " +
"FROM sys_LogOperation " +
"GROUP BY YEAR(OperationTime); ";
DataSet ds = DatabaseProvider.SystemDatabase.GetDataSet(sql1 + sql2);
return ds;
}
//来源:C/S框架网 | www.csframework.com | QQ:23404761

参考文档:
CSFrameworkV6 - Winform开发框架 - Delete方法使用
CSFrameworkV6 - Winform开发框架 - GetLookupData方法使用
Winform软件快速开发框架(使用DevExpress正版授权皮肤组件)
使用Winform代码生成器生成FastReport.NET报表模板文件(frx文件)
Winform开发框架 - 使用Linq判断日期时间范围查询条件的方法
CSFrameworkV6 - 基础资料窗体 - ShowSummary方法使用
Winform软件开发框架使用DevExpress组件有那些优势?|软件平台
Winform界面布局控件太多没有出现滚动条XtraScrollableControl组件使用
Winform Html Editor 使用kindeditor组件实现winform Html 编辑器
HtmlAgilityPack编程 - 使用DocumentNode.InnerText去除HTML标签-C/S开发框架
C# SharpMap的简单使用-C/S开发框架
Web端使用VUE调用WebApi接口实现用户登录及采用Token方式数据交互
C# Winform等待窗体WaitingForm组件下载(CSFramework提供)|C/S开发框架
Winform开发框架 | 表格编辑窗体权限控制|C/S开发框架
.NET代码生成器V6.1 - 快速生成Winform窗体代码
C# DevExpress教学 GridLookUpEdit组件表格下拉组件使用|C/S开发框架
CSFrameworkV6 - Winform开发框架 - Delete方法使用
CSFrameworkV6 - Winform开发框架 - GetLookupData方法使用
Winform软件快速开发框架(使用DevExpress正版授权皮肤组件)
使用Winform代码生成器生成FastReport.NET报表模板文件(frx文件)
Winform开发框架 - 使用Linq判断日期时间范围查询条件的方法
CSFrameworkV6 - 基础资料窗体 - ShowSummary方法使用
Winform软件开发框架使用DevExpress组件有那些优势?|软件平台
Winform界面布局控件太多没有出现滚动条XtraScrollableControl组件使用
Winform Html Editor 使用kindeditor组件实现winform Html 编辑器
HtmlAgilityPack编程 - 使用DocumentNode.InnerText去除HTML标签-C/S开发框架
C# SharpMap的简单使用-C/S开发框架
Web端使用VUE调用WebApi接口实现用户登录及采用Token方式数据交互
C# Winform等待窗体WaitingForm组件下载(CSFramework提供)|C/S开发框架
Winform开发框架 | 表格编辑窗体权限控制|C/S开发框架
.NET代码生成器V6.1 - 快速生成Winform窗体代码
C# DevExpress教学 GridLookUpEdit组件表格下拉组件使用|C/S开发框架
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 |
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 |
在线客服
