1、需求描述

最近碰到了一个需求,是要统计各个团队的员工的销售金额,然后一级一级向上汇总。

​编辑

架构团队树是类似于这种样子的,需要先算出每个员工的销售金额,然后汇总成上一级的团队金额,然后各个团队的销售总金额再往上汇总成一个区域的销售金额,然后各个区域的金额再往上汇总成总公司的金额。当然我工作碰到的团队树要远比这个复杂许多,但反正差不多是这么个意思。

2、解决方法

2.1、方法一(不推荐)

持久层通过一些sql把团队树结构,以及各个员工的销售金额汇总拿到,然后在业务层通过代码去一层层拼起来。这是我一开始拿到这个需求时的思路,后来发现可以但是很复杂,代码可读性及可维护性很差。

2.2、方法二(推荐)

在sql里面计算汇总出来。

我这里是在测试环境建了几张Demo表来加以说明sql的逻辑。

1、建表、

CREATE TABLE Business..TGroupV2(TreeNodeNo int,TeamId int,TeamName varchar(100),[Path] varchar(100));
CREATE TABLE Business..TPeopleSalesInfoV2(TeamId int,PeopleId varchar(100),PeopleName varchar(100));
CREATE TABLE Business..TPeopleSalesDetailInfoV2(PeopleId varchar(100),Amount Decimal(18,2),ContractID varchar(100));

2、添加一些测试数据

​编辑

3、SQL代码

--以团队为单位,汇总各个团队,子团队,父团队的销售金额
SELECT TB.TreeNodeNo,TB.TeamID,TB.TeamName,AA.Amount,'' as PeopleId ,'' as PeopleName FROM
(
SELECT A.ParentTeamID,SUM(A.Amount) as Amount FROM
(
SELECT
TT.*,TG2.TeamID as ParentTeamID,BB.Amount from
(
select T1.*,TG.[Path]
from Business..TPeopleSalesInfoV2 T1
left join Business..TGroupV2 TG on T1.TeamId=TG.TeamId
) AS TT
left join Business..TGroupV2 TG1 on TT.TeamId=TG1.TeamId
left join Business..TGroupV2 TG2 on
TG1.[Path] LIKE ('%\' + convert(varchar(50),TG2.TeamID))
or TG1.[Path] like ('%\' + convert(varchar(100),TG2.TeamID) + '\%')
or TG1.[Path] like (convert(varchar(50),TG2.TeamID) + '\%')
or TG1.[Path] = convert(varchar(50),TG2.TeamID)
LEFT JOIN
(select PeopleId,SUM(Amount) as Amount from Business..TPeopleSalesDetailInfoV2 group by PeopleId)
as BB on TT.PeopleId=BB.PeopleId
) A GROUP by ParentTeamID
) as AA LEFT JOIN Business..TGroupV2 TB on TB.TeamID=AA.ParentTeamID
UNION
--以员工为单位获取各个销售人员的销售金额
select TB.TreeNodeNo,TB.TeamID,TB.TeamName,SUM(TP.Amount) as Amount,TP.PeopleId,TPS.PeopleName from Business..TPeopleSalesDetailInfoV2 TP
LEFT JOIN Business..TPeopleSalesInfoV2 TPS on TPS.PeopleId=TP.PeopleId
LEFT JOIN Business..TGroupV2 TB on TB.TeamID=TPS.TeamID
group by TB.TreeNodeNo,TB.TeamID,TB.TeamName,TP.PeopleId,TPS.PeopleName
ORDER BY TreeNodeNo,PeopleId ASC

​编辑

2.3、思路说明

​编辑

3、总结

随着数据量增加一些老的sql查询性能太慢了,经常出现这种查询超时问题。

​编辑

造成这种问题的原因有很多,一种是sql写的太烂了,业务层有循环查询。就像我方法一中的那种思想,不可避免你要循环查询出每个团队的金额再一级一级向上汇总。还有就是不合理的权限控制。比如你要查询团队的销售金额。因为团队的关系是一个树状结构嘛。假如你是东区的领导,你只能查询东区及其下所有子团队的数据,但在权限判断这块,其实是会东区下每个子团队,以及子团队的子团队.....都要判断一遍你有没有查询的权限。这样就增加了不必要的负担。不过这个是历史遗留问题,是因为之前的权限结构设计就不完善,也不太好改。

解决方法嘛,目前我就是通过存储过程取代select查询,因为存储过程是预编译的,所以执行起来开销比较小所以速度比较快。可以看下这篇详细了解下:为什么存储过程比sql语句效率高? - herizai - 博客园 (cnblogs.com)

因为原先的select查询关联了好多表以及视图,各种join的,可读性很差。我所要做的就是理清这些join之间的关系, 存储过程中用几个临时表把大的join拆成合并成小的join。再加一些注释什么的,虽然业务没有变,只是代码更容易理解了。速度确实快了一些,不在出现查询的超时的问题了。

4、参考资料

为什么要用存储过程,存储过程的优缺点。。_jokeylin的博客-CSDN博客

为什么存储过程比sql语句效率高? - herizai - 博客园 (cnblogs.com)

sql根据团队树一级一级汇总统计的更多相关文章

  1. SQL基础-汇总统计及GROUP BY

    一.汇总统计 1.聚集函数 COUNT() 计算总数 SUM() 求和 MAX() 最大值 MIN() 最小值 AVG() 平均值 2.聚集函数使用 总共有多少名学生? SELECT COUNT(*) ...

  2. SQL SERVER 月、季、年统计与常用查询语句汇总

    一.SQL SERVER 月.季.年统计查询 --本天 SELECT *FROM dbo.TableName WHERE DATEDIFF(DAY,TimeField,getdate())= 0; - ...

  3. 每日学习心得:SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析)

    2013-8-20 1.    SQL查询表的行列转换/小计/统计(with  rollup,with cube,pivot解析) 在实际的项目开发中有很多项目都会有报表模块,今天就通过一个小的SQL ...

  4. oracle pipelined返回值函数 针对数据汇总统计 返回结果集方法

    近期需要一个汇总统计,由于数据太多,数据量太大所以在java程序中实现比较困难.若用后台程序统计,数据不能保证实时,同时实现周期比较长.顾使用函数返回结果集的方式,在不增加临时表的情况下实时获取数据. ...

  5. SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析)

    SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析) 2013-8-20 1.    SQL查询表的行列转换/小计/统计(with  rollup,with ...

  6. 你真的会玩SQL吗?实用函数方法汇总

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  7. 64位 SQL Server2008链接访问Oracle 过程汇总解决方法记录

    64位 SQL Server2008链接访问Oracle 过程汇总解决方法记录 经过几天不停的网上找资料,实验,终于联通了. 环境:系统:win 2008 ,SqlServer2008 R2, 连接O ...

  8. AspxGridView 数据的汇总统计

    AspxGridView底部增加数据汇总行 这个功能在AspxGridView中不用复杂的代码实现, 实际上只是设置下GridView的属性而已 1. ShowFooter设置为True,即显示. 位 ...

  9. 国内顶尖的sql dba 团队招人。

    国内顶尖的sql dba 团队招人. 4年DBA 经验 我们希望你掌握 1.熟练关系型数据库原理.熟练一门语言(C# .Java.Python.powershell ) 2.对自动化.数据化感兴趣. ...

  10. 如何用C#对Gridview的项目进行汇总统计?

    上一次用了javascript对gridview进行了汇总统计,但那个统计是在客户端进行的,虽然减轻了服务器的负担,但是,当需要把统计信息汇出excel时,汇总信息却死活不出来了,所以,绕半天又绕回来 ...

随机推荐

  1. Codeforces Round #710 (Div. 3)

    emmm,就ac了3题 A题转换推下公式. tB题模拟,在第一个与最后一个变x后,直接i下标+k,判断当前下标前一个befor与最后一个last距离是否>k,是的话在当前下标往前找*字符然后改为 ...

  2. MQ系列6:消息的消费

    MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 在之前 ...

  3. Selenium+Python系列 - 开发环境搭建

    一.写在前面 我从未想过自己会写python系列的自动化文章,有些同学会问,那你现在为什么又开始写了? 不止一个人找过我,问我可以写一些Python自动化的文章吗,答案是肯定的. 笔者Java党,整P ...

  4. Nginx通用优化示例

    user nginx; worker_processes auto; #worket_cpu_affinity auto; error_log /var/log/nginx/error.log war ...

  5. Windows活动目录_票据——敬请期待!

    票据:域控&域机子之间的信任密钥 [缺省40天更换一次] 域用户登录过程 域用户的账户密码(用信任密钥加密的)传递至域控: 域控验证账户密码成功后,构造域用户SID和组SID(用信任密钥加密的 ...

  6. SQL语句编写的练习(MySQL)

    SQL语句编写的练习(MySQL) 一.建表 1.学生表(Student) 学号 | 姓名 | 性别 | 出生年月 | 所在班级 create table Student( sno varchar(2 ...

  7. FileNotFoundError: Could not find module libmxnet.dll

    解决方法:把CUDA的bin目录下的dll文件全部复制到libmxnet.dll所在的目录 问题原因:libmxnet.dll引用了一些CUDA的dll,但是找不到路径.

  8. 一、Vue.js介绍

    一.介绍 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手 ...

  9. RDF/RDFS/OWL

    RDF(Resource Description Framework 资源描述框架) 知识总是以三元组形式出现: (subject, predicate, object) 即 (主,谓,宾) 资源和属 ...

  10. 安装nvm 和 yarn

    安装nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash 执行上面的命令 如果出现问题 ...