Chinaunix首页 | 论坛 | 博客
  • 博客访问: 163560
  • 博文数量: 20
  • 博客积分: 1610
  • 博客等级: 上尉
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-16 15:40
文章分类

全部博文(20)

文章存档

2013年(1)

2012年(2)

2011年(8)

2010年(1)

2009年(2)

2008年(2)

2007年(4)

分类:

2007-03-16 17:31:21

  • 问题描述:
这个问题的财务、超市、销售中经常出现, 商品类别经常有大类、大类中有小类,小类中有小小类,呵呵,前几个编号都一致,然后细分细分,在财务里面可能会细分到7层次,当然号别也比较固定,一般1,3,5,7,这样设置段位,不会乱设置,在一般的系统中商品都录入在一张表中,然后类表在别的表中,一般是这么设计的。 现在假定商品流水信息在这个 CashValue 这个表中,记录了 最细节的单位商品的确切信息,如下所示。
  • 要求:
统计各个分类的和。有多少类别统计多少个类别。
  • 分析:
假定在事先已经知道了各个类别的分类段号,那还好做一些,直接几个union all 能解决,
如果这个类型日后的发展可能会变化,会不断添加,
就是说 可能会3位,5位,7位,再可能会 9位。
这是写好固定几个就不是很好用了。
  • 解决:
  动态取得具体的段位数,然后根据这个数来截位取得汇总信息。

select substr(Code,1,D.DD) ,sum(Amount)
        From CASHValue,
        (select distinct length(Code) DD From CashCode ) D
group by substr(Code,1,D.DD)
Order by substr(Code,1,D.DD),length(substr(Code,1,D.DD))

 
结果为:
 
 1      2    
 -----  -----
 A      21.00
 A01    6.00 
 A0101  1.00 
 A0102  2.00 
 A0103  3.00 
 A02    15.00
 A0201  4.00 
 A0202  5.00 
 A0203  6.00 
 B      60.00
 B01    22.00
 B0101  5.00 
 B0102  8.00 
 B0103  9.00 
 B02    38.00
 B0201  10.00
 B0203  10.00
 B0204  18.00
 18 record(s) selected [Fetch MetaData: 0/ms] [Fetch Data: 0/ms]
 [Executed: 07-3-16 下午05时04分25秒 ] [Execution: 0/ms]
 
 
  • 注意点:
通过笛卡儿积故意构造了几种类别的冗余数据,例如将 A 大类表的数据,全部列了出来,统计A的就是全部A分类的东西,有时故意的冗余不见得就是坏事,至少我这么认为。
这样就很巧妙的实现了这个不同类别的统计。

select substr(Code,1,D.DD) ,Amount ,D.DD
        From CASHValue,
        (select distinct length(Code) DD From CashCode ) D

 
 1      AMOUNT     DD   
 -----  ---------  -----
 A      1.00       1    
 A      2.00       1    
 A      3.00       1    
 A      4.00       1    
 A      5.00       1    
 A      6.00       1    
 B      5.00       1    
 B      8.00       1    
 B      9.00       1    
 B      10.00      1    
 B      10.00      1    
 B      18.00      1    
 A01    1.00       3    
 A01    2.00       3    
 A01    3.00       3    
 A02    4.00       3    
 A02    5.00       3    
 A02    6.00       3    
 B01    5.00       3    
 B01    8.00       3    
 B01    9.00       3    
 B02    10.00      3    
 B02    10.00      3    
 B02    18.00      3    
 A0101  1.00       5    
 A0102  2.00       5    
 A0103  3.00       5    
 A0201  4.00       5    
 A0202  5.00       5    
 A0203  6.00       5    
 B0101  5.00       5    
 B0102  8.00       5    
 B0103  9.00       5    
 B0201  10.00      5    
 B0203  10.00      5    
 B0204  18.00      5    
 36 record(s) selected [Fetch MetaData: 0/ms] [Fetch Data: 0/ms]
 [Executed: 07-3-16 下午05时22分30秒 ] [Execution: 15/ms]
 
附录上 建表插入数据的SQL。
 


create table CashValue (Code Varchar(20),Amount decimal(10,2))
drop table CashValue ;
Create table CashCode (Code varchar(10),Name varchar(20) )
select * From CASHVALUE
insert into CashCode values ('A','吃' ) ;
insert into CashCode values ('A01','肉类' ) ;
insert into CashCode values ('A02','蛋类' ) ;
insert into CashCode values ('A03','水果类' ) ;
insert into CashCode values ('B','衣' ) ;
insert into CashCode values ('B01','夏衣' ) ;
insert into CashCode values ('B02','秋衣' ) ;
insert into CashCode values ('B03','冬衣' ) ;
insert into CashCode values ('B0301','冬皮衣' ) ;

delete from CASHCODE ;
insert into CashValue values ('A0101',1) ;
insert into CashValue values ('A0102',2) ;
insert into CashValue values ('A0103',3) ;
insert into CashValue values ('A0201',4) ;
insert into CashValue values ('A0202',5) ;
insert into CashValue values ('A0203',6) ;
insert into CashValue values ('B0101',5) ;
insert into CashValue values ('B0102',8) ;
insert into CashValue values ('B0103',9) ;
insert into CashValue values ('B0201',10) ;
insert into CashValue values ('B0203',10) ;
insert into CashValue values ('B0204',18) ;

还有一个函数 Rollup,Cube 等等这样的,也是可以统计分组、总分组的东西,

但是这个是对不同字段有效。
看了一下没研究出来,要是谁会用别的方法写出来,也请告诉我,不胜感激啊。
阅读(1826) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~