zoukankan      html  css  js  c++  java
  • SQL实现交叉表的方法

     

    转帖自http://www.allwiki.com/wiki/SQL%E5%AE%9E%E7%8E%B0%E4%BA%A4%E5%8F%89%E8%A1%A8%E7%9A%84%E6%96%B9%E6%B3%95

    交叉一般来讲是分组统计的一种,形式更复杂,显示更清淅,但数据库本身并没有提供实现交叉表的功能,自己创建交叉表不仅要对过程、游标、临时表、动态SQL等非常熟悉,而且思路也要清淅,本例以PUBS.DBO.SALES表的数据做样本:
    CREATE PROCEDURE UP_TEST(
    @T1 VARCHAR(30),@T2 VARCHAR(30),
    @T3 VARCHAR(30),@T4 VARCHAR(30)) AS
    --T1 表名,T2,T3是交叉表的两上分类字段,T4是汇总字段
    --T2是行字段,T3列字段
    BEGIN
    DECLARE @SQL VARCHAR(7999),@FIELD VARCHAR(30)
    SELECT @SQL='SELECT DISTINCT '+@T3+' FROM '+@T1
    CREATE TABLE #FIELD(FIELD VARCHAR(30))
    --将列字段提取到临时表#FIELD中
    INSERT INTO #FIELD EXEC(@SQL)
    SELECT @SQL='CREATE TABLE CROSS_TEST('+@T2+' VARCHAR(30),'
    DECLARE CUR_FIELD CURSOR LOCAL FOR SELECT * FROM #FIELD
    OPEN CUR_FIELD
    FETCH CUR_FIELD INTO @FIELD
    WHILE @@FETCH_STATUS=0 BEGIN
    SELECT @FIELD='['+@FIELD+']'
    SELECT @SQL=@SQL+@FIELD+' DECIMAL(8,2) DEFAULT 0,'
    FETCH CUR_FIELD INTO @FIELD
    END
    SELECT @SQL=LEFT(@SQL,LEN(@SQL)-1)+')'
    --创建临时交叉表CROSS_TEST
    EXEC(@SQL)
    SELECT @SQL='INSERT INTO CROSS_TEST('+@T2+') SELECT DISTINCT '+@T2+' FROM '+@T1
    --将行数据存入交叉表#CROSS_TEST
    EXEC(@SQL)
    --创建分组数据表TEMP
    SELECT @SQL='CREATE TABLE TEMP('+@T2+' VARCHAR(30),'+@T3+' VARCHAR(30),'+@T4+' DECIMAL(8,2))'
    EXEC(@SQL)
    --将交叉汇总数据放入交叉表
    SELECT @SQL='SELECT '+@T2+','+@T3+', SUM(QTY) QTY FROM '+@T1 +' GROUP BY '+@T2+','+@T3
    INSERT INTO TEMP EXEC(@SQL)
    --将汇总数据写入交叉表
    DECLARE CUR_SUM CURSOR LOCAL FOR SELECT * FROM TEMP
    DECLARE @F1 VARCHAR(30),@F2 VARCHAR(30),@QTY DECIMAL(8,2),@Q1 VARCHAR(30)
    OPEN CUR_SUM
    FETCH CUR_SUM INTO @F1,@F2,@QTY
    WHILE @@FETCH_STATUS=0 BEGIN
    SELECT @F2='['+@F2+']',@Q1=CAST(@QTY AS VARCHAR(30))
    SELECT @SQL='UPDATE CROSS_TEST SET '+@F2+'='+@Q1+' WHERE '+@T2+'='''+@F1+''''
    EXEC(@SQL)
    FETCH CUR_SUM INTO @F1,@F2,@QTY
    END
    CLOSE CUR_SUM
    SELECT * FROM CROSS_TEST
    DROP TABLE TEMP
    DROP TABLE CROSS_TEST
    DROP TABLE #FIELD
    END

    说明:字段加中括号为了处理字段中含有特殊字符,值得注意得是要实现交叉表的表必须有两个分类,本例只支持分类字段的数据类型是字符型的,最大的问题就是高亮显示这行的WHERE条件啦,字符类型字段查询时条件必须加单引号,如果是数值类型就可以直接写,所以数值类型的分类字段更容易实现一些,更可以融合在一个过程中。通常大家看到的交叉表都有行汇总与列汇总等信息,本例就没有实现,最后一点工作大家自己练练手吧。

  • 相关阅读:
    为什么gitHub提交记录显示作者名称是unknow?
    hibernate的面向对象查询的效率有多低?
    Cesium中文网——如何开发一款地图下载工具[一]
    使用Cesium的地下渲染技术可视化瑞士的地质资源
    用Cesium可视化地下设施、矿山和地质层
    CesiumJS新增官方TypeScript类型定义
    Cesium1.70-介绍CesiumOSM建筑新特性
    宣布与Epic Games合作,为虚幻引擎创造Cesium
    地底,TypeScript和全球3D建筑发布于CesiumJS 1.70
    CesiumJS下载量超过1百万次
  • 原文地址:https://www.cnblogs.com/malingbo/p/1619102.html
Copyright © 2011-2022 走看看