zoukankan      html  css  js  c++  java
  • 查询分类并实现分类统计SQL存储过程

    问题描述:

    实现无限级查询和分类统计数据SQL存储过程。详细数据表设计如下:


    设计的数据表
    表一:PUb_Dict --用于存放分类表,理论上可以存放无限级,现有三级
    DictId --编号
    DictName --名称
    ParentId --父类编号(根级用0表示)

    另外一个表 pub_Info 信息引用这上面表DictId编号作为分类信息
    表结构大致如下:
    InfoID --自动编号
    Infotitle --标题
    InfoDate --时间
    InfoContent --内容
    DictId ---引用分类编号

    表pub_Info 的分类可能同时存在 一级(如101)、二级(如101001)和三级(101001001)的分类数据
    现在要分级统计各分类数量,同时在程序界面上显示分类名称、编号和统计结果.
    另外要注意: 如果是父类的分类统计数据要包含子类的数量。

    如:一级要包含二和三级,二级要包含三级。
    分类为 101 的统计结果还要包含底下所有子分类的结果(如101001,101002,101003...)

     备注:因为服务器平台问题,数据库是SQL2000的

    那么我实现方法如下:

    /**************************************************************************** 
    *取得各种产品分类的ID,名称和统计条数 
    *创建时间:2010-09-21 
    *@rId:相当于父类编号(第一级为0)
    *@typeCode varchar(10), --子分类代码 
    *@tblName:表名
    *@IdName:信息表引用的分类编号字段名称,如pub_Info表引用为(Res_Id)
    *@strWhere:附加过滤条件字符串,不用加关键词where,如:State=2,多个组合用AND拼接 
    调用例子:EXEC USP_Pub_GetPurveyResTypeCount 30102,'T','pub_info','Res_Id','State=2 AND Area_Id=10501' 
    ************************************************************************************/ 
    CREATE PROC USP_Pub_GetResTypeCount ( 
    @rId int,--类别编号代表父类 
    @typeCode varchar(10), --子分类代码
    @tblName varchar(50),--表名称
    @IdName varchar(50),--ID列的名称
    @strWhere varchar(200)--过滤条件
    )
    AS
    BEGIN
    
    --创建临时表
    CREATE TABLE #tt(
    [DictId]int primary key,
    [DictName] varchar(50),
    [Total] int
    )
    DECLARE
    @i int,--索引号
    @tCount int, --统计数据
    @max int,--最大分类编号
    @min int,--最小分类编号
    @len int,--编号的长度
    @dName varchar(50), --分类名称
    @SQL nvarchar(1000),--查询SQL语句
    @subLen int
    
    IF(@typeCode='T')
    SET @subLen=2  --计算长度,因为有些是:10101001,有些是1010010001形式的
    ELSE SET @subLen=3 
    
    SET @len=LEN(@rId)
    SET @min=(SELECT MIN(DictID) FROM  Pub_Dict WHERE ParentId=@rId AND typeCode=@typeCode)
    SET @max=(SELECT MAX(DictID) FROM  Pub_Dict WHERE ParentId=@rId AND typeCode=@typeCode)
       
     SET @i=@min
           WHILE(@i<=@max)
    	 BEGIN
                   SET @SQL='SELECT @tCount=Count(1) FROM '+@tblName+' WHERE SUBSTRING(CAST('+@IdName+' AS VARCHAR(20)),1,CAST('+CAST(@len AS VARCHAR(10))+' AS INT))='+CAST(@i AS VARCHAR(20))+' AND '+@strWhere
                   EXECUTE SP_EXECUTESQL @SQL,N'@tCount INT OUTPUT',@tCount OUTPUT
    
                    SET @dName=(SELECT DictName FROM Pub_Dict WHERE DictId=@i)
    	   INSERT INTO #tt values(@i,@dName,@tCount)
                    SET @i=@i+1
    	 END
    
    SELECT * FROM #tt --查询输出结果
    
    DROP Table #tt --删除临时表
    
    END
    
    GO
    
    

    虽然用这种方法能够较灵活实现了此功能,但每次调用都创建临时表,删除临时表,数据量大的时候,性能是一个值得思考的问题。但是到目前为止,想不到更好的办法,期待各位的解决方案。
  • 相关阅读:
    利用dockerfile定制镜像
    发布Docker 镜像到dockerhub
    Docker 停止容器
    133. Clone Graph
    132. Palindrome Partitioning II
    131. Palindrome Partitioning
    130. Surrounded Regions
    129. Sum Root to Leaf Numbers
    128. Longest Consecutive Sequence
    127. Word Ladder
  • 原文地址:https://www.cnblogs.com/cgli/p/1861318.html
Copyright © 2011-2022 走看看