• 全部
  • 基础类
  • 应用实例
  • 新技术前沿

请教一个统计的存储过程,我的想法是用游标的嵌套,但是却又担心效率.

tristsesame 杭州快睿 开发组长/高级工程师/技术专家  2003-11-06 04:25:04
一个帐户表:TabAccount(acctID)
一个用户表:TabUser(userID,acctID)

一个帐户可以有多个用户.
同一个账户下的每个用户的费用都是从该帐户中扣除。

对应于这个存储过程,我现在的想法是这样的.

在结帐的时候,
先检索出所有的帐户.这里要用到一个游标.设为游标A

然后再检索该帐户下的所有用户,再用到一个游标,设为游标B

统计该用户的费用

不为空的话,则下一个用户

生成该帐户的一条帐户记录,插入到相应的表中.

不为空,则下一个帐户


这样就要用到游标的嵌套,
但我总是担心效率问题。因为有的表可能有上百万个记录。

有点迷茫,
大家帮帮忙,提提意见。谢了,呵呵
...全文
32 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
tristsesame 2003-11-07
多谢mybios

我现在也觉得好像也只能用二级游标来做了.

以前是只用了一个游标,
但是生成用户的帐单中"起始金额"和"终止金额",都只是用“起始金额"减去该用户的费用,得到
“终止金额”的
这样对帐户和用户是一一对应的倒没错,

若该帐户下有多个用户的话,用户看到那帐单会糊涂的,
只有该帐户下最后结算的用户的余额是和帐户中的余额是一致的.
呵呵,所以要改写过了。
回复
tristsesame 2003-11-07
简要说明一下.
一个帐户表:TabAccount(acctID,Money,...) --Money指的是该帐户的金额.
一个用户表:TabUser(userID,acctID,...) --FK acctID

一个开通业务表:TabUserSrv(UserID,SrvID)
一个业务表TabSrv(SrvID,MonthBill) --MonthBill指该业务的月租费用

中间还有些如
用户充值记录表TabFill、转帐记录表等

对每个用户都需生成帐单:
其中必须要有的"起始金额"和"终止金额"
而金额只有帐户中有。

而这"终止金额"并不能简单的用"起始金额"减去该用户的费用,
而是要减去所有和该用户在同一帐下的所有用户的费用。

每个用户根据所开的业务不同,所以费用也都不同,都需单独计算的.

利用视图我觉得似乎没有必要.
回复
mybios 2003-11-07
to tristsesame:
呵呵。的确是这样。慢慢用游标玩吧。。不错的。虽然速度慢悠悠的,不过思路很清晰,不会写错。。
回复
tangxc2003 2003-11-07
insert 相应的表 (userid,费用) s
elect userID,sum(费用)
from TabUser
group by userID
回复
zjcxc 元老 2003-11-06
光从你给的表中,不能看出更多的东西,你最好举例说明.


只从你的文字描述中,可以这样考虑.
分组统计各用户的费用,做一个视图
利用帐号和上面的视图建立关联,做出第二个视图,得到各帐户的费用
生成结果.
回复
mybios 2003-11-06
跟一般的进销存的概念差不多。只是你进出的是金钱,而进销存进出的是货品。
在计算每一个用户的时候不能直接用一句简单的inner join或者left outer join就可以实现的,这个时候我一般会用游标来实现,这个时候就必须用两级游标了。
但是,在第二级游标的时候,你可以尽量把一些可以用inner join的就用inner join,尽量缩减合计变量的数量,这就可以尽量提高效率了。
一般一两小时执行完整年的进销存数据我也试过。你那个看来是移动业务数据表吧,即使运行一两小时也没有什么问题啊。我看移动的计费也是这样的吧,计费都是要一两天才能出来的。
我觉得效率不是问题,主要是用游标写出来的程序比用inner join或者left outer join写出来的清晰很多。
回复
tristsesame 2003-11-06
一个帐户表:TabAccount(acctID)
一个用户表:TabUser(userID,acctID)

一个开通业务表:TabUserSrv(UserID,SrvID)
一个业务表TabSrv(SrvID,MonthBill) --MonthBill指该业务的月租费用

中间还有些如
用户充值记录表TabFill、转帐记录表等

这些都是属于统计之中。

因此每个用户的统计包括多种费用。
这些都需要保存到用户帐单表中。

而用户帐单的字段包括“起初余额、月租费用、业务月租费用...、终止余额.

其中起初余额和终止余额应该是帐户中的金额.

而该用户的帐户的终止余额,只有在统计完该帐户下所有用户之后才能计算出来。
这个统计就是这点比较麻烦的.
回复
zjcxc 元老 2003-11-06
--例如:
一个帐户表:TabAccount(acctID)
一个用户表:TabUser(userID,acctID)
一个费用表:Tabexpens(userid,expens)

那就可以这样统计:
insert into 结果表(accid,expens)
select a.accid,expens=sum(b.expens)
from tabuser a inner join tabexpens b on a.userid=b.userid
group by a.accid
回复
zjcxc 元老 2003-11-06
楼主最好给出表示例.
回复
zjcxc 元老 2003-11-06
--这样不行吗? 为什么要用游标

insert into 相应的表(acctID,费用总计)
select accid,sum(费用总计) from 费用表
回复
tristsesame 2003-11-06
费用并没有放在TabUser表中,
需要到别的表中读取,例如,
在统计一个用户的费用时.
查看该用户使用了哪些业务,哪些业务的月租费用又是多少多少等.
所以对每个用户,都需要一个检索并统计的过程.

而最终要给这个用户所看到的,是他在某个时间段内,他所花费的钱及他所在的帐户余额的变化。

而帐户中所花费的钱,有可能是该帐户中别的用户所花掉的,并不全是他个人所用到的。

大多数的帐户和用户是一一对应的关系的,
但也有些帐户是一对多的,即一个帐户对应多个用户。
回复
pengdali 2003-11-06
insert 相应的表 (userid,费用) select userID,sum(费用) from TabUser group by userID

??
回复
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2003-11-06 04:25
社区公告
暂无公告