SQL树形数据的一种解决方法
来源:互联网 发布:windows.old还原win10 编辑:程序博客网 时间:2024/06/04 23:08
业务需求:
一份电梯购买合同包含多个设备,合同和设备信息分布存储于合同表和设备表,每一个合同有一个业绩归属人,每一个设备有一个业绩归属人,一般情况下
合同的业绩所属人跟所辖的设备业绩所属人都是一样的,但是存在一些情况合同里面的设备业绩所属人各个不同。
现在要查询合同基本信息,但是要附加一列统计合同里面 设备业绩所属人+设备数目的信息,例如合同号13J001/010 设备号是13J001到13J010
其中3台业绩人是张三,5台是李四,2台是王五,那么该列信息应该显示 张三3,李四5,王五2
原始解决方法:
很容易想到的一种解决方法就是写一个标量值函数,传进去一个合同ID,然后select出这些设备信息,使用游标遍历拼出来这样一个字符串,返回。
代码我就不写了,实在是很简单。写完之后部署到服务器上,虽然合同数据只有1万条左右,但是出奇的慢,慢到无法加载数据。我想这个函数计算
逻辑也不是很复杂啊,怎么慢到这种程度呢?
唉,无奈,优化下。
想了下并不是所有合同中的设备业绩所属人都是不一致的,那我查询之前加个判断,如果你存在这种多个情况我就调用函数,不存在我就不调用呗。
修改之,部署到测试环境,果然快了很多,但是还是要10s左右的加载速度,不满意还要继续优化。
优化方案:
之前方案为什么会这么慢呢?很肯定的原因就是我用了函数和游标,SQL执行时候是无法优化函数语句的,游标的遍历执行也是很耗费资源,那么我们能不能
利用连接查询之类的方法实现需求呢?答案是肯定的,首先看下我们现在设备表的数据:
前面是合同ID,后面是 设备业绩人和数目,我们要的最终效果是下面这样的:
看一下第一张图,其实按照合同ID去group的话,我们可以按照顺序给name编出次序1 2 3等,就像下面的这个样子:
这样的话就很像一棵树了,我们要做的就是根据树的ID先分出类来,然后根据level_num一个个的把name加到前一个name中去。
下面是最终的SQL,明白上面的道理应该很同意就能看懂:
;WITH EquSm AS (SELECT constractid,(sm.name+CAST(COUNT(Salesmanid) AS VARCHAR(10))) as nameFROM EquipmentForConstract efc LEFT JOIN SalesMan sm on efc.salesmanid=sm.idWHERE stateforupdate='正常'GROUP BY constractid,Salesmanid,sm.name ),EquSmLevel AS( --构造层级树 SELECT constractid,name,ROW_NUMBER()OVER(PARTITION BY constractid ORDER BY constractid) AS level_num FROM EquSm),EquSmLs AS( SELECT constractid,CAST(name AS NVARCHAR(100)) AS name,level_num FROM EquSmLevel WHERE level_num=1 UNION ALL SELECT m.constractid,CAST(m2.name+','+m.name AS NVARCHAR(100)) AS name,m.level_num FROM EquSmLevel AS m INNER JOIN EquSmLs AS m2 ON m.constractid=m2.constractid AND m.level_num=m2.level_num+1),EquSmMaxLv AS( SELECT constractid,MAX(level_num) AS level_num FROM EquSmLs GROUP BY constractid),SignmanTb AS(SELECT A.constractid,A.name as signmanFROM EquSmLs AS A INNER JOIN EquSmMaxLv AS B ON A.constractid=B.constractid AND A.level_num=B.level_num )select * from SignmanTb
参考:http://www.cnblogs.com/dataadapter/archive/2012/07/19/2598506.html
- SQL树形数据的一种解决方法
- SQL树形数据的处理
- (转)SQL树形数据的处理1
- SQL SERVER 2008不能连接本地服务器的一种解决方法
- mysql导入sql文件出错的一种解决方法
- mysql导入sql文件出错的一种解决方法
- mysql导入sql文件出错的一种解决方法
- C#串口通信时丢失数据的一种解决方法
- C#串口通信时丢失数据的一种解决方法
- 数据结果集的一种透传解决方法
- SQL Server 中树形表数据的处理总结
- Related to Oracle SQL 关于树形数据的遍历
- SQL中利用递归函数取树形结构的数据
- sql查询树形结构的数据 n+1问题
- topK的一种解决方法
- 树形数据的处理
- 树形数据的处理
- 树形数据的处理
- 第九次实验任务
- 进程的创建与可执行程序的加载
- jQuery plugin Validation的7个Callback介绍
- Hibernate的实体类中为什么要继承Serializable?
- Xoreax IncrediBuild 4.60
- SQL树形数据的一种解决方法
- Oracle命令--alter 操作
- IOS成长之路-使用系统默认声音、震动
- Oracle命令--update操作
- 第九次上机报告
- XFire WebService 服务
- 源于频率的困惑——GSM空中接口物理层的设计
- PGA统计信息相关
- ORA-02055: distributed update operation failed; rollback required