数据库问题,大家多多帮忙!(95分)

  • 主题发起人 主题发起人 Fuweng
  • 开始时间 开始时间
F

Fuweng

Unregistered / Unconfirmed
GUEST, unregistred user!
下面是我自己假想的一道题目,有点象ISP计算我们的上网费用,但更复杂些,
我们每次上网都要访问很多网站,假设ISP能记录下这些详细情况.

表结构如下:

表A: (用户上网详细记录表)

用户帐号 网站名称 开始时间(秒) 结束时间(秒)
001 网易 2000-6-7 00:00:00 2000-6-7 00:01:38
002 搜狐 2000-6-7 00:01:08 2000-6-7 00:01:31
001 新浪 2000-6-7 00:10:01 2000-6-7 00:10:10
001 大富翁 2000-6-7 00:18:06 2000-6-7 00:35:30
002 21CN 2000-6-7 00:30:00 2000-6-7 00:57:45
............................

表B: (网站费率对照表)
网站名称 费率(元/分钟)
网易 0.01
新浪 0.02
搜狐 0.04
大富翁 0.01
21CN 0.07
......................


上面表A中每条记录的费用计算规则如下:

[结束时间]减去[开始时间],将所得的秒数换算成分钟,
小于17秒, 记为0分钟;
大于等于17秒,小于1分钟, 记为1分钟;
等于60秒, 当然记为1分钟;
大于1分钟小于2分钟, 记为2分钟;
大于2分钟小于3分钟, 记为3分钟;
依次类推
然后,将表A和表B关联起来,用刚才算出的分钟乘以表B中的费率,就得到每条
记录的费用.

现在要算的是:
1.在一段时间内各个网站的收费总金额的排名
2.在一段时间内各个用户帐号的收费总金额的排名

其实上面的题目我已经算出来了,我是将所有数据都取出来在外面算的,
显然效率很低,没有体现出数据库的优势.我总觉得用SQL语言会比较好,
水平所限,弄不好!

麻烦各位大侠帮我想一下更好的计算方法,

要求是:
1. 不能改变源数据库.
2. 速度要快,效率要高.
3. 将结果在DBGrid中显示出来
4. 如果是本地数据库(如:Access97),该怎样做比较好;
如果是SQL数据库(如:MS SQL Server),该怎样做比较好;
5. 最好给出代码.

先谢了!! (95分,全部家当了)
 
觉得不可行,http 是时断时续的,不能简单的用记时来算时间。
 
SQL数据库:
select A.用户帐号,B.费率,A.网站名称,
DATEDIFF(minute,A.开始时间,A.结束时间) time,
DATEDIFF(minute,A.开始时间,A.结束时间)*B.费率 money
from yourtableA A,yourtableB B
where A.用户帐号=B.用户帐号
以上函数minute处可以为:day,hour,second等,
不能实现[结束时间]减去[开始时间],将所得的秒数换算成分钟,
小于17秒, 记为0分钟;
大于等于17秒,小于1分钟, 记为1分钟;
等于60秒, 当然记为1分钟;
大于1分钟小于2分钟, 记为2分钟;
大于2分钟小于3分钟, 记为3分钟; 依次类推 。。。
只能实现精确的minute或second

 
to SuperMMX:
答非所问!我在一开始就说得很清楚--这是我自己假想的一道题目,所以表A
是怎么来的不用管,只须回答我的问题.

to wumeng:
你的Select语句我早就知道,但此题就是难在下列条件上,

>> [结束时间]减去[开始时间],将所得的秒数换算成分钟,
>> 小于17秒, 记为0分钟;
>> 大于等于17秒,小于1分钟, 记为1分钟;
>> 等于60秒, 当然记为1分钟;
>> 大于1分钟小于2分钟, 记为2分钟;
>> 大于2分钟小于3分钟, 记为3分钟;
>> 依次类推

必须要有这些条件!!否则我就不用问别人了!!


to All:
我想既然涉及到计算问题,仅仅用Select是不行的,或许还得用Update什么的.
对于本地数据库(如:Access97),是不是应该建立临时表,但临时表怎么建,建完后
怎样将记录放进去,然后又怎样对其进行操作,比如:用Select * from AAA,本来
AAA应该是硬盘里的数据表,可现在记录在临时表中,那么AAA又是什么呢?我对临时
表确实很糊涂.哪位大侠能给一段代码(包括:临时表的建立,使用,删除).
我不知道TBatchMove和TUpdateSQL这两个控件是否能用上,但我想即便用上,也
非这两个控件建立的初衷.
对于SQL数据库(如:MS SQL Server),显然最好的方法是存储过程,还有视图什
么的,我一直没搞懂.

还请各位大侠多多帮忙!! 这95分若不够,日后可补上.
 
经典的方法:专解决此难题,若你不能与我上面的方法合成,把下面作成试图。
select empNo,time=case
when ( DATEDIFF(second,datetimebegin,datetimeend)%60>17
and DATEDIFF(minute,datetimebegin,datetimeend)<1)
then 1
when ( DATEDIFF(second,datetimebegin,datetimeend)%60>=0
and DATEDIFF(minute,datetimebegin,datetimeend)>0)
then (DATEDIFF(minute,datetimebegin,datetimeend)+1)
end
from Askleave
 
sql server 用 case when 语句;
access 用 switch 函数.
创建临时表用 select .. into #AAA
 
to gxg8816 ,wumeng :
二位大侠,庶小弟愚笨,能不能再说得详细点,多谢!
 
为什么没人理我!快来人啊!
 
to gxg8816 ,wumeng :
二位大侠,庶小弟愚笨,能不能再说得详细点,多谢!
快来人啊!快来人啊!
 
第一步:计算上网秒数,生成临时表#tb1
select 用户帐号,网站名称,DATEDIFF(minute,A.开始时间,A.结束时间) AS time
into #tb1
from yourtableA

第二步: 计算上网分钟数,生成临时表#tb2
select 用户帐号,网站名称 minite = case when time ... then
into #tb2
from #tb1
第三步: #tb2 同费率表连接按网站名group 汇总费用;
第四步: #tb2 同费率表连接按用户账号group 汇总费用;




 
to gxg8816:
多谢!多谢!你曾说过如果是Access97的话用switch,
请再将相应的第二步提示一下!
 
函数
Switch(expr-1, value-1[, expr-2, value-2 ?[, expr-n,value-n]])
Access帮助中的例子:

x = Switch([ShipCity] = "Madrid", "Spanish", _
[ShipCity] = "Berlin", "German", _
[ShipCity] = "Torino", "Italian", _
[ShipCountry] = "France", "French", _
True, "English")

假如城市是 Madrid,Switch 函数返回 Spanish;假如是 Berlin,Switch 函数返回 German,依此类推。假如城市不在所列的城市中,但国家为法国,它将返回 French。如果城市不在列表中,Switch 函数返回 English。


Access 中也可用iif 函数,不过嵌套太多了;
Sql 中目前只能用case when 子句,写起来很长,据说SQL 2000 支持自定义函数,那就好了.

你可以把一、二、三 和 一、二、四 分别做成写成存储过程
 
让各位大侠久等了,这段时间正在看"存储过程"方面的书,再次感谢gxg8816,wumeng
二位大侠!

gxg8816: 55
wumeng : 40

 
多人接受答案了。
 
后退
顶部