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. Mapper 实体转换Entiy to Dto

    实际使用中发现很多问题 如果用EFcore 框架,这个表达式树生成一个新的实体导致EFcore 跟踪失败!/// <summary> /// 生成表达式目录树 泛型缓存 /// </ ...

  2. 快速上手Mybatis项目

    快速上手Mybatis项目 思路流程:搭建环境-->导入Mybatis--->编写代码--->测试 1.搭建实验数据库 CREATE DATABASE `mybatis`; USE ...

  3. Shading-JDBC、ShadingSphere、ShardingProxy 使用详解

    ShadingSphere ​ShardingSphere是一款起源于当当网内部的应用框架,2015年在当当网内部诞生,2016年由主要开发人员张亮带入京东数科,在国内经历了当当网.电信翼支付.京东数 ...

  4. 测试杂谈——一条SQL引发的思考(二)

    在前段时间,曾写过一篇关于SQL问题的文章,测试杂谈--一条SQL引发的思考(一). 今天这篇,算是个问题记录吧,问题并不复杂,但对于测试同学而言,确实是个需要关注的点. 问题分析 最近在日常工作中, ...

  5. RE语法

    RE,英文为Regular Expression,中文译作正则表达式.用于文本过滤的工具.RE语法由一些元字符.其它任意字符串作为基本单元,匹配次数.分组匹配.锚定符等为操作单元组成.进行逐行扫描,满 ...

  6. resutful的使用和增强版的swagger2

    1.REST的特征 统一接口:客户和服务器之间通信的方法必须统一,RESUTFUL风格的数据元操作CRUD分别对应HTTP方法----GET用来获取数据源,POST用来新建资源,PUT用来更新资源,, ...

  7. 基于BP神经网络的手MNIST写数字识别

    import numpy import math import scipy.special#特殊函数模块 import matplotlib.pyplot as plt #创建神经网络类,以便于实例化 ...

  8. maven的下载、安装、配置,idea中配置Maven

    下载 下载链接: 点击下载地址 : 找到:对应版本的包下载 安装 下载后的压缩包解压出来,然后将解压后的包放到日常安装软件的位置即安装成功,当然取决于个人意愿,也可以不移动. 打开安装包后的目录结构简 ...

  9. VirtualBox 下 CentOS7 静态 IP 的配置 → 多次踩坑总结,蚌埠住了!

    开心一刻 一个消化不良的病人向医生抱怨:我近来很不正常,吃什么拉什么,吃黄瓜拉黄瓜,吃西瓜拉西瓜,怎样才能恢复正常呢? 医生沉默片刻:那你只能吃屎了 环境准备 VirtualBox 6.1 网络连接方 ...

  10. 检测轮廓 获取其最值的坐标 opencv-python

    一.基础知识 图像清晰度评价算法有多种 空域中,主要考察图像的邻域对比度,即相邻像素间灰度特征的 梯度差: 频域中,主要考察图像的频率分量,清晰的图像高频分量多,模糊的图像低频分量多. 灰度值 把白色 ...