`

用SQL实现统计报表中的“小计”和“合计”

 
阅读更多

在开发统计报表的过程中,经常会碰到在查询到的数据集中,插入一些小计行和合计行。比如在烤烟系统中,几乎每个统计报表都需要加入“合计”行,还有不少涉及到烟叶等级的统计报表需要加入各烟叶等级的小计行。我看到不少人(包括我自己)都是在程序中专门写一些方法来处理的,有的方法还很繁琐。最近在看SQL Server2000的联机丛书中才发现,利用GROUPING聚合函数和ROLLUP运算符可以轻松实现统计中加入小计和合计功能。

1.      GROUPPINGROLLUP的基本知识

1.1.    GROUPPING

是一个聚合函数,它产生一个附加的列,当用 CUBE 或 ROLLUP 运算符添加行时,附加的列输出值为1,当所添加的行不是由 CUBE 或 ROLLUP 产生时,附加列值为0。

语法: GROUPING ( column_name )
参数: column_name是 GROUP BY 子句中用于检查 CUBE 或 ROLLUP 空值的列。
返回类型: int
备注: 分组用于区分由 CUBE 和 ROLLUP 返回的空值和标准的空值。作为CUBE 或 ROLLUP 操作结果返回的 NULL 是 NULL 的特殊应用。

1.2.    ROLLUP

ROLLUP 运算符生成聚合汇总, 需要汇总信息时,此运算很有用。该运算符生成的结果集类似于 CUBE 运算符生成的结果集。但它们两者有一些区别,CUBE 生成的结果集显示了所选列中值的所有组合的聚合。而ROLLUP 生成的结果集显示了所选列中值的某一层次结构的聚合。

语法: ROLLUP ( column_name1[,column_name2。。。] )
用法: 用在GROUP BY 子句中。对那些需要按其分组,并对其分组的聚合数据进行汇总的列,就请对这些列加上ROLLUP运算符。
注意: “GROUP BY ROLLUP(col1,col2)”与“GROUP BY ROLLUP(col1),ROLLUP(col2)”是有区别的。“GROUP BY ROLLUP(col1),ROLLUP(col2)”其实就相当于“GROUP BY CUBE(col1,col2)”,因为它对每个分组的聚合都要进行汇总。“GROUP BY ROLLUP(col1,col2)”与“GROUP BY ROLLUP(col2,col1)”也有区别,前者是对每个col1的唯一值都产生一个在col1下各个col2聚合值汇总的行,再对所有col1与col2的聚合值产生一个汇总行;而后者是对每个col2的唯一值都产生一个在col2下各个col1聚合值的汇总行,再对所有col1与col2的聚合值产生一个汇总行。这样说逻辑可能不太清晰,我们看一下下面的图表就一目了然了。

col1

col2

amount

col1

col2

amount

3

2

3584777

3

2

3584777

3

3

12774875

4

2

200789.1

3

16359652

5

2

274432

4

2

200789.1

2

4059998

4

3

8619498

3

3

12774875

4

 

8820288

4

3

8619498

5

2

274432

5

3

2024463

5

3

2024463

3

23418837

5

2298895

27478835

27478835

GROUP BY ROLLUP(col1,col2)的效果 

GROUP BY ROLLUP(col2,col1)的效果 

 

2.      实际案例

我们现在就来看一个Oracle9i中的统计示例,示例如下:

2.1.    统计要求

开发一个关于各烟叶等级的二次验级的原发件数、原发重量及验收重量的统计报表。其中,原发件数、原发重量和验收重量等列要求计算出各等级组别的小计和所有记录的合计。

2.2.    我们通常的做法

1.用下面的SQL统计出初步的数据集。

 

SELECT  T1.TOBACCO_CLASS_NAME,
                 T4.TOBACCO_CLASS_TYPE,
                NVL(SUM(T1.ORG_PIECE), 0) TOTAL_ORG_PIECE,
                 NVL(SUM(T1.ORG_WEIGHT), 0) TOTAL_ORG_WEIGHT,
                 NVL(SUM(T1.AMOUNT), 0) TOTAL_AMOUNT
   FROM  VI_FK_BALANCE_DETAIL T1, TB_TOBACCO_CLASS T4
WHERE  T1.TOBACCO_CLASS_ID=T4.TOBACCO_CLASS_ID
                 AND T1.ACCOUNT_YEAR=T4.ACCOUNT_YEAR
                 AND T4.DEL_FLAG=0
                 AND T4.ENABLE_FLAG=0
                 AND T1.REC_DATE > TO_DATE(‘2006-11-05’, ‘YYYY-MM-DD
GROUP  BY  T4.TOBACCO_CLASS_TYPE,T1.TOBACCO_CLASS_NAME
 ORDER   BY  T4.TOBACCO_CLASS_TYPE

查询的结果如下表所示

烟叶等级

等级组别

原发件数

原发重量

验收重量

(B1F)上桔一

51

4945

197800

197508.1

(B2F)上桔二

51

8335

333400

332316.9

(C1F)中桔一

51

694

27760

27610.54

(C2F)中桔二

51

803

32120

31650.4

(C3F)中桔三

51

6381

255240

255372.6

(X1F)下桔一

51

75

3000

3012.2

(B3F)上桔三

52

4701

188040

187389.9

(B4F)上桔四

52

122

4880

4866.81

(C3V)中微青三

52

174

6960

6934.06

(C4F)中桔四

52

4639

185560

185276.4

(X2F)下桔二

52

1739

69560

69029.79

(X2V)下微青二

52

26

1040

1038.34

(X3F)下桔三

52

1263

50520

50439.86

(X4F)下桔四

53

102

4080

4075.62

(B3K)上杂三

54

0

0

249.39

                            

2.再在程序中编写相应的方法对查询得到的数据集进行处理。我们的重点不是在怎么写处理数据集的方法上,所以相应的方法在此略去。

 

 

2.3.      用SQL直接实现的方法

 

SELECT DECODE(GROUPING(T4.TOBACCO_CLASS_TYPE) + GROUPING(T1.TOBACCO_CLASS_NAME),
                               1,
                               DECODE(T4.TOBACCO_TYPE,
                                                  51, ‘上等烟小计’,
                                                  52, ‘中等烟小计’,
                                                  53, ‘下等烟小计’,
                                                  54, ‘低等烟小计’,
                                                  ‘小计’),
                               2,
                               ‘合计’,
                               T1.TOBACCO_CLASS_NAME
                 ) TOBACCO_CLASS_NAME,
                   T4.TOBACCO_CLASS_TYPE,
                   NVL(SUM(T1.ORG_PIECE),0) TOTAL_ORG_PIECE,
                   NVL(SUM(T1.ORG_WEIGHT), 0) TOTAL_ORG_WEIGHT,
                   NVL(SUM(T1.AMOUNT), 0) TOTAL_AMOUNT
 FROM     VI_FK_BALANCE_DETAIL T1, TB_TOBACCO_CLASS T4
WHERE    T1.TOBACCO_CLASS_ID=T4.TOBACCO_CLASS_ID
                   AND T1.ACCOUNT_YEAR=T4.ACCOUNT_YEAR
                   AND T4.DEL_FLAG=0
                   AND T4.ENABLE_FLAG=0
                   AND T1.REC_DATE > TO_DATE(‘2006-11-05’, ‘YYYY-MM-DD
GROUP   BY   ROLLUP( T4.TOBACCO_CLASS_TYPE,T1.TOBACCO_CLASS_NAME)
ORDER   BY  T4.TOBACCO_CLASS_TYPE

  

通过查询得到统计结果如下表所示,该表的统计结果已经满足了统计要求。

烟叶等级

等级组别

原发件数

原发重量

验收重量

(B1F)上桔一

51

4945

197800

197508.1

(B2F)上桔二

51

8335

333400

332316.9

(C1F)中桔一

51

694

27760

27610.54

(C2F)中桔二

51

803

32120

31650.4

(C3F)中桔三

51

6381

255240

255372.6

(X1F)下桔一

51

75

3000

3012.2

上等烟小计

51

21233

849320

847470.8

(B3F)上桔三

52

4701

188040

187389.9

(B4F)上桔四

52

122

4880

4866.81

(C3V)中微青三

52

174

6960

6934.06

(C4F)中桔四

52

4639

185560

185276.4

(X2F)下桔二

52

1739

69560

69029.79

(X2V)下微青二

52

26

1040

1038.34

(X3F)下桔三

52

1263

50520

50439.86

等烟小计

52

12664

506560

504975.1

(X4F)下桔四

53

102

4080

4075.62

下等烟小计

53

102

4080

4075.62

(B3K)上杂三

54

0

0

249.39

低等烟小计

54

0

0

249.39

合计

33999

1359960

1356771

 

 

    通过比较,相信大家也感觉到后者的独特魅力了吧。至少我在写那些对数据集处理得到小计行的方法的时候,感到虽不是很复杂,但也是有些繁琐的,远不如直接在SQL中实现小计来得潇洒、简洁。

分享到:
评论

相关推荐

    用SQL实现统计报表中的小计与合计的方法详解

    接着,为了实现小计和合计,我们创建另一个临时表#TB1。在这个过程中,我们会用到标识符(identity)列来区分原始数据和计算的数据。通过`SELECT * INTO #TB1 FROM #TB WHERE 1<>1`,我们创建了一个空的#TB1表,保留...

    使用ROLLUP函数生成报表的小计、合计

    在数据库查询操作中,经常需要对数据进行分组统计,并在此基础上进一步生成包含小计和总计的报表。这种需求在人力资源管理系统(如文中提到的eHR系统)以及其他各类业务系统中非常常见。本文主要探讨如何利用SQL中的...

    用SQL实现统计报表中的"小计"与"合计"的方法详解

    在SQL中,生成统计报表中的"小计"与"合计"是常见的数据分析需求,这通常涉及到数据的分组和聚合。以下将详细讲解如何通过SQL实现这一功能。 首先,我们来看一下三种不同的实现方法: 1. **GROUPING SETS与ROLLUP**...

    用友U8自定义报表使用存储过程时,使用系统的分组和小计、累计、合计

    用友U8自定义报表使用存储过程时,使用系统的分组和小计、累计、合计是指在用友U8自定义报表中使用存储过程来生成报表,同时利用系统的分组和小计、累计、合计功能来实现报表的统计和分析。 在用友U8中,自定义报表...

    使用SQL实现小计,合计以及排序

    在SQL(Structured Query Language)中,实现小计、合计及排序是数据分析和报表制作中常见的需求。本示例中,我们将探讨如何通过SQL语句来完成这个任务。 首先,我们创建了一个临时表#TB,用于存储测试数据。该表...

    SQL 合计函数.rar

    本资料“SQL 合计函数.rar”可能包含有关SQL中常用的总计函数的详细解释和示例。 1. SUM() 函数:SUM() 是最基础的合计函数,它返回指定列的所有数值的总和。例如,如果你有一个销售表,你可以用SUM()函数计算所有...

    SQL查询技术在报表统计中的应用.pdf

    SQL(Structured Query Language)是一种数据库查询和程序设计语言,用于存储、检索和操作数据库中的数据。它是关系数据库管理系统的标准语言,被广泛应用于数据处理和报表统计。本文将深入探讨SQL查询技术在报表...

    如何在水晶报表中添加合计字段源程序实例,C#.net源代码编写,

    在Crystal Reports中添加合计字段是报表设计中的常见需求,它能够帮助我们快速计算并展示数据的总和、平均值等统计信息。以下是一个基于C#.NET和Visual Studio .NET的详细步骤来实现这一功能。 首先,确保你已经...

    SQL 函数集.rar

    SQL Server提供GROUP BY语句结合聚合函数(如SUM, AVG, COUNT, MAX, MIN)来实现小计。比如,你可以按地区分组并计算每个地区的销售额总和。GROUP BY允许在多个级别上创建层次化的小计,使用HAVING子句可以进一步...

    Sql Server 分组统计并合计总数及WITH ROLLUP应用

    总结一下,`Sql Server`中的`WITH ROLLUP`操作符是进行分组统计并生成包含小计和总计报表的有效方法。它与`GROUP BY`结合使用,可以方便地生成层次化的总计,帮助用户快速理解数据的分布和总量。通过理解并熟练运用`...

    标准SQL语句参考手册

    在“SQL 参考手册.chm”中,您将找到更多关于这些函数以及SQL其他方面的详细解释和示例,包括如何在实际的QueryDef对象和Recordset对象中使用它们,以实现更复杂的查询操作。通过深入学习这本手册,您将能够掌握标准...

    sql rollup用法 小计汇总

    这样,我们就可以在结果中区分出省份汇总(标记为“合计”)和城市汇总(标记为“小计”)。 总的来说,`ROLLUP` 提供了一种简便的方式,用于生成多层次的汇总数据,它可以用于复杂的分析和报表生成,尤其是在需要...

    SQL中的各类函数大全

    以下是对标题“SQL中的各类函数大全”以及描述中提及的“内部合计函数”和“日期与时间函数”的详细解析。 ### 一、内部合计函数 #### COUNT(*) `COUNT(*)`是最常用的聚合函数之一,用于计算指定列或所有行的数量...

    U8自定义报表功能介绍

    - **分组汇总**与**小计与合计**:可实现数据的分类汇总,提供快速统计功能。 - **按编码规则展开列**:尤其适用于编码结构复杂的企业,便于查看和理解数据层次。 - **分组分页打印**:根据数据分组进行分页打印...

    sql高级查询

    SQL标准中的CONNECT BY和START WITH语句可用于实现这种类型的查询。 #### 四、其他高级功能 - **分析函数**:如`LEAD`, `LAG`, `RANK`, `DENSE_RANK`等,用于执行更复杂的行间分析。 - **外部数据库操作**:某些...

    sql小计汇总 rollup用法实例分析

    通过CASE语句,我们可以根据GROUPING函数的值为汇总行添加“小计”或“合计”标签。 在示例中,ROLLUP操作按照province和city字段生成了以下层次的汇总: - 城市级别的汇总(如广东的东莞、广州和珠海) - 省份级别...

    分组后分组合计以及总计SQL语句(稍微整理了一下)

    在SQL中,分组和聚合操作是数据分析和报表制作中常用的功能。本文将详细解析标题和描述中提及的“分组后分组合计以及总计”的概念,并通过示例来阐述如何实现这些操作。 1. **分组后分组合计** - 当我们需要对数据...

    总分类帐户余额试算表.doc

    此外,总分类帐户余额试算表也可以与其他财务工具和技术相结合,例如财务报表、财务预算、财务分析等,以实现财务管理的自动化和智能化。通过对总分类帐户余额试算表的应用和分析,企业可以获得更加科学和可靠的财务...

Global site tag (gtag.js) - Google Analytics