Sql语法高级应用之五:使用存储过程实现对明细多层次统计
前言
前面章节我们讲到了存储过程的基础用法,本章则将一个在项目中实际应用的场景。
在项目中经常会存在这样的需求,例如需要对明细列表进行按组、按级别、按人等进行统计,如果在附带列表的查询条件,又如何实现呢?
一般的思路是:先拿到明细数据,然后分别按照组,级别,人进行统计得到三个集合。
正确的做法应该是:客户需要什么维度的统计就获取当前维度的列表即可,在程序中要尽可能避免用不到的逻辑处理。
下面附上我的解决方案:
方案
我的方案是:利用存储过程将查询条件与统计维度的标示通过参数传递给存储过程,存储过程则负责返回统计后的结果。
下面附上实际案例:
存储过程代码
USE Wot_Inventory; GO
-- 判断要创建的存储过程名是否存在
IF EXISTS
(
SELECT *
FROM dbo.sysobjects
WHERE id = OBJECT_ID(N'[Wot_Inventory].[dbo].[sp_nodeliverystatistics]')
AND OBJECTPROPERTY(id, N'IsProcedure') = 1
)
-- 删除存储过程
DROP PROC [sp_nodeliverystatistics];
GO
CREATE PROC [sp_nodeliverystatistics]
(
@ListName NVARCHAR(16), --列表名称
@Nav NVARCHAR(16), --导航名称
@Where VARCHAR(MAX), --查询条件
@msg NVARCHAR(200) OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sqlStr NVARCHAR(MAX); BEGIN TRY
IF @ListName <> ''
AND @ListName IS NOT NULL
AND @Nav <> ''
BEGIN IF (@ListName = 'Agreed')
BEGIN
SET @sqlStr
= N'SELECT ' + @Nav
+ ',COUNT(Id) Number,SUM(Receivable) TotalReceivable,AVG(Receivable) AvgReceivable,SUM(AgencyFund) TotalAgencyFund,AVG(Receivable) AvgAgencyFund FROM Wot_Inventory.dbo.NoDeliveryByDetailView WHERE 1 = 1';
EXEC (@sqlStr + @Where + N' GROUP BY ' + @Nav + '');
SET @msg = '列表统计成功';
END;
ELSE IF (@ListName = 'Immediate')
BEGIN
SET @sqlStr
= N'SELECT ' + @Nav
+ ',COUNT(Id) Number,SUM(Receivable) TotalReceivable,SUM(AgencyFund) TotalAgencyFund,SUM(InsurreValue) TotalInsurreValue,SUM(FragileInsurreValue) TotalFragileValue FROM Wot_Inventory.dbo.NoDeliveryByDetailView WHERE 1 = 1';
EXEC (@sqlStr + @Where + N' GROUP BY ' + @Nav + '');
SET @msg = '列表统计成功';
END;
ELSE
BEGIN
SET @msg = '传递的参数不正确';
END; END;
ELSE
BEGIN
SET @msg = '传递的参数不正确';
END;
END TRY
BEGIN CATCH
SET @msg = ERROR_MESSAGE();
PRINT @msg;
END CATCH;
PRINT @msg;
END;
GO
存储过程Sql
程序代码
List<AgreedStatistics> dtoResult1 = new List<AgreedStatistics>();
List<AgreedStatistics> dtoResult2 = new List<AgreedStatistics>();
List<AgreedStatistics> dtoResult3 = new List<AgreedStatistics>();
List<AgreedStatistics> dtoResult4 = new List<AgreedStatistics>();
List<AgreedStatistics> dtoResult5 = new List<AgreedStatistics>(); //按预约
string sql = "EXEC Wot_Inventory.dbo.sp_nodeliverystatistics @ListName, @Nav, @Where, @msg OUT";
var sqlwhere = "";
sqlwhere = SetSqlWhere(sqlwhere, request, user, "Dtl");
SqlParameter[] parms = new SqlParameter[]
{
new SqlParameter("@ListName","Agreed"),
new SqlParameter("@Nav","AgreedDate"),
new SqlParameter("@Where",sqlwhere),
new SqlParameter("@msg",System.Data.SqlDbType.NVarChar,)
};
parms[].Direction = System.Data.ParameterDirection.Output; dtoResult1 = deliverRepository.ExecuteSql<AgreedStatistics>(sql, parms).OrderByDescending(t => t.TotalReceivable).ToList();
msg = parms[].Value.ToString();
dtoResult1.ForEach(t =>
{
t.Id = index1++;
}); //销售组
string sql2 = "EXEC Wot_Inventory.dbo.sp_nodeliverystatistics @ListName, @Nav, @Where, @msg OUT";
var sqlwhere2 = "";
sqlwhere2 = SetSqlWhere(sqlwhere2, request, user, "Dtl");
SqlParameter[] parms2 = new SqlParameter[]
{
new SqlParameter("@ListName","Agreed"),
new SqlParameter("@Nav","SalesGroupName"),
new SqlParameter("@Where",sqlwhere2),
new SqlParameter("@msg",System.Data.SqlDbType.NVarChar,)
};
parms2[].Direction = System.Data.ParameterDirection.Output; dtoResult2 = deliverRepository.ExecuteSql<AgreedStatistics>(sql2, parms2).OrderByDescending(t => t.TotalReceivable).ToList();
msg = parms2[].Value.ToString();
dtoResult2.ForEach(t =>
{
t.Id = index2++;
});
后台代码
前端效果

在当前案例中,我使用了缓存,在查询明细的同时,将所有维度的统计缓存起来,因为考虑到这个明细的列表不会产生太多的数据。这也是一种解决问题的思维,具体按实际情况而定。
PS:欢迎扫描下方二维码或点击链接,加入QQ群


Sql语法高级应用之五:使用存储过程实现对明细多层次统计的更多相关文章
- Sql语法高级应用之三:存储过程
一.存储过程概述 SQL Server中的存储过程是使用T_SQL编写的代码段.它的目的在于能够方便的从系统表中查询信息,或者完成与更新数据库表相关的管理任务和其他的系统管理任务.T_SQL语句是SQ ...
- Sql语法高级应用之七:如何在存储过程中使用事务
普通事物: USE Wot_Inventory; GO BEGIN TRANSACTION tr; DECLARE @error INT; SET @error = 0; SELECT * FROM ...
- Sql语法高级应用之六:如何在Sql语句中如何使用TRY...CATCH
TRY...CATCH使用范例 BEGIN TRY //逻辑语句块 END TRYBEGIN CATCH //Catch异常处理块 SET @msg = ERROR_MESSAGE(); PRINT ...
- Sql语法高级应用之二:视图
SQL CREATE VIEW 语句 什么是视图? 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列,就像一个真实的表.视图中的字段就是来自一个或多个数据库中的真实的表中 ...
- Sql语法高级应用之一:使用sql语句如何实现不同的角色看到不同的数据
前言 在常见的管理系统中,通常都有这样的需求,管理员可以看到所有数据,部门可以看到本部门的数据,组长可以看到自己组的数据,组员只能看到自己相关的数据. 一般人的做法是,根据不同的角色通过if...el ...
- Sql语法高级应用之四:使用视图实现多表联合数据明细
之前章节我们讲到:如果某个表的数据是多个表的联合,并且存在列与列的合并组成新列,用视图是最好的方案. 下面我分享两个个真实的SQL语句案例 USE Wot_Inventory GO FROM sys. ...
- SQL语法基础之高级应用
SQL语法基础之高级应用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.存储过程与函数 1>.CREATE PROCEDURE 用来创建存储过程 mysql> ? ...
- 高级数据查询SQL语法
接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL语法, ...
- SQL Server高级内容之case语法函数
1.Case函数的用法 (1)使用类似:switch-case与if-else if. (2)语法: case [字段] when 表达式 then 显示数据 when 表达式 then 显示数据 ...
随机推荐
- Mysql总结(一)
数据库命令:创建create database 数据库名 charset=utf8;删除drop database 数据库名;查看所有数据库:show databases;使用数据库:use 数据库名 ...
- Cmder的安装
Cmder把conemu,git-for-windows和clink打包在一起,让你无需配置就能使用一个真正干净的Linux终端!性感的外观,强大的功能!代替了Windows原生的Cmd 1. 安裝 ...
- U3D 如何计算一个UI四个角的绝对坐标
//方式一,使用API获取 var rtrans = gameObject.GetComponent<RectTransform>(); Vector3[] worldcorners ...
- IIS记录
IIS中SSL配置.导入:http://www.cnblogs.com/whitewolf/archive/2010/07/07/1773066.html
- An Introduction To Value at Risk (VAR)
http://www.investopedia.com/articles/04/092904.asp http://www.jpmorgan.com/tss/General/email/1159360 ...
- XSS学习笔记
本片文章是读<<XSS跨站脚本gj剖析与防御>>一书的总结 常见的XSS攻击主要用于1.网络钓鱼,盗用用户账号2.窃取cookies 非httponly情况下,读取docume ...
- hra 直线
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...
- C语言条件编译及编译预处理阶段(转)
一.C语言由源代码生成的各阶段如下: C源程序->编译预处理->编译->优化程序->汇编程序->链接程序->可执行文件 其中 编译预处理阶段,读取c源程序,对其中的 ...
- IRC聊天指南
参考https://www.cnblogs.com/fzzl/archive/2011/12/26/2302637.html
- 借用服务器百度BAE
3一.简介 对于普通的开发者,不必要买服务器和买域名,这时要将自己的项目传到服务器上,就用到了百度BAE这样的,可以直接传项目的服务器. 二.申请 登录百度开放平台上 三.登录网址,选择要使用的项目 ...