茶叶面包 发表于 2013-7-27 09:46:09

微复杂的Oracle统计报表

本帖最后由 茶叶面包 于 2013-7-27 09:50 编辑

做统计报表不得不说到SQL的联接,而且SQL的联接是学习oracle数据库的基础中的基础,所以下面简要的
阐述一下理论。
一、概述
    关系理论的3个支柱是选择、投影、联接。使用联接可以将不同表或视图的行相互联系起来。联接支持暗示数据库中存储数据的方式。有几种方法可以联接表的,最常见的方法称为同等联接,该联接依据列值或表达式的相等性将一行与另一个表中的一行或多行关联起来,还可以使用非同等联接来联接表。在这种联接中,行与另一个表中的一行或多行关联起来,前提是这些行的列值在由不等于运算符确定的范围之内。
    另一种不常见的方法是将这些行与同一个表中的其他行关联起来。这种关联建立在列之上,
这些列相互之间有逻辑关系以及层次结构关系。这种联接称为自联接。当执行同等联接和非同等联接时,会排除包含空值或公共联接列中具有不同条目的行。如果有必要的话,可以使用外联接来获得单行。当来自一个表的所有行联接到另一个表的所有行时,就会形成笛卡尔乘积。这种联接通常是
遗漏联接条件或联接条件不充足的结果,但有时也故意为之。
二、联接分类
1、同等联接和非同等联接
2、自联接
3、外联接
(1)左外联接(2)右外联接(3)全外联接
以上关于具体每种联接的含意、示例、用法在这里不做详细说明,更多相关知识可以查看Oracle官方文档。
三、需求场景
看如下图,在数据库里面有两张表,产品价格表和价格范围表,通过编写SQL语句来实现统计报表的效果。

1、创建两张表并插入数据SQL> desc product_price;
Name    Type         Nullable Default Comments
------- ------------ -------- ------- --------
PRODUCT VARCHAR2(25) Y
PRICE   NUMBER       Y
SQL> desc extend_price;
Name      Type   Nullable Default Comments
----------- ------ -------- ------- --------
START_PRICE NUMBER Y
END_PRICE   NUMBER Y
SQL> select * from product_price;
PRODUCT                        PRICE
------------------------- ----------
a                                  2
b                                  3
c                                 11
d                                 11
e                                 12
f                                 35
g                                 34
h                                 23
i                                 33
j                                 66
k                                 10
11 rows selected
SQL> select * from extend_price;
START_PRICEEND_PRICE
----------- ----------
0          9
10         19
20         29
30         39
40      99999
2、分析
既然是要显示成统计报表的形式内容,那么首先得拿着product_price表的price列值与extend_price
表的start_price/end_price列进行比较才能确定在哪些区间有多少产品。(如果大家有更好的理解欢迎互相讨论!)SQL> SELECT
2CASE
3      WHEN b.start_price || '元到' || b.end_price || '元' LIKE '0%'
4      THEN '10元以下'
5      WHEN b.start_price || '元到' || b.end_price || '元' LIKE '4%'
6      THEN '40元以上'
7      ELSE b.start_price || '元到' || b.end_price || '元'
8      END EXTEND_PRICE,
9      SUM (
10            CASE
11             WHEN a.price >= b.start_price AND a.price <= b.end_price
12                  THEN 1
13                  ELSE 0
14                  END
15            ) PRODUCT_COUNT
16            FROM product_price a, extend_price b
17            WHERE a.price >= b.start_price AND a.price <= b.end_price
18            GROUP BY
19                  CASE
20                        WHEN b.start_price || '元到' || b.end_price || '元' LIKE '0%'
21                        THEN '10元以下'
22                        WHEN b.start_price || '元到' || b.end_price || '元' LIKE '4%'
23                        THEN '40元以上'
24                        ELSE b.start_price || '元到' || b.end_price || '元'
25                        END ORDER BY 1;
EXTEND_PRICE                                                                     PRODUCT_COUNT
-------------------------------------------------------------------------------- -------------
10元以下                                                                                     2
10元到19元                                                                                 4
20元到29元                                                                                 1
30元到39元                                                                                 3
40元以上                                                                                     1
SQL>
3、讨论
假设某一结果集:
月份 、功率分布情况、数量
2013-01 功率小于70   30
2013-01 功率70         21
2013-01 功率71         30
2013-01 功率72         35
2013-01 功率73         40
2013-01 功率74         44
2013-01 功率75         41
2013-01 功率大于75   40
你认为产生这种结果集的表应该怎么样设计才更好?
希望大家可以相互讨论一翻,应该还有比较好的设计或写法的。

guo 发表于 2013-8-28 10:51:13

顶一下

shifouwan 发表于 2014-3-8 21:53:21

不知楼主听过一个报表软件没有,finereport,有免费的。我现在一直在用,这种程度的统计报表只是小意思啦。有时候不一定要借助很复杂很绕的SQL脚本,通过外物一样可以实现。还请楼主遇到这样的问题能三思啊,不要一味的强求自己的SQL脚本能力,费时费力。。。还是交给专业的辅助软件来干吧。:P
页: [1]
查看完整版本: 微复杂的Oracle统计报表