CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  基础类

微软面试题,Sql

楼主jilongge(果子)2001-11-20 17:18:35 在 MS-SQL Server / 基础类 提问

一百个账户各有100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后,请输出每天所有账户的余额信息, 问题点数:20、回复次数:169Top

1 楼icevi(按钮工厂)回复于 2001-11-20 17:20:35 得分 0

又不知道表结构怎么写?Top

2 楼icevi(按钮工厂)回复于 2001-11-20 17:22:28 得分 0

比如不知道这个期初100¥是不是在表里有记录啊?  
  Top

3 楼jilongge(果子)回复于 2001-11-20 17:24:27 得分 0

自己建立table。依赖性太强了你。Top

4 楼icevi(按钮工厂)回复于 2001-11-20 17:30:39 得分 0

不会吧??这样说我???  
  你的题目也太简洁了点吧?  
  Top

5 楼jilongge(果子)回复于 2001-11-20 17:34:07 得分 0

自己想吧,一切全靠自己。Top

6 楼mtdata(不写代码的日子)回复于 2001-11-20 17:38:01 得分 0

好像有点难度Top

7 楼microyzy(人不在牛,分高就行;分不在高,人牛也行)回复于 2001-11-20 17:38:02 得分 10

“表”结构  
  账号         vchar  
  时间         datetime  
  余额         int  
   
  select   min(余额),[账号],时间   from   表   group   by   时间,账号  
   
  不知行不行?Top

8 楼firedragoninhell(SZGODDON)回复于 2001-11-20 17:40:51 得分 0

给点提示。比如,“输出”是怎么样的输出?Top

9 楼icevi(按钮工厂)回复于 2001-11-20 17:42:05 得分 0

取余额倒不是最麻烦的。麻烦的是每天的都要选出来。如果当天没有任何数据,怎样生成这个数就有点麻烦了。做存储过程肯定是可以的。  
   
  不知道能不能做存储过程啊?Top

10 楼leorb(◥银狐◣)回复于 2001-11-20 17:46:00 得分 10

select   日期,账户,  
      (  
      select   min(金额)  
      from   表名  
      where   账户=别名.账户   and   日期   between   一百天前   and   别名.日期  
      )   余额  
  from   表名   别名  
  where   日期   between   一百天前   and   一百天后  
  order   by   日期,账户  
  group   by   日期,账户Top

11 楼BCB2000(棒槌)回复于 2001-11-20 17:49:56 得分 0

的有两个表吧Top

12 楼nononono(null,null)回复于 2001-11-20 17:57:53 得分 0

1.   建立一个临时表,   有一个自增字段,   用来产生天数(1-100),按这个表与原表进行连接  
  2.   是不是需要考虑一天内有2笔以上的记录?  
   
  一条语句我不能做到.  
  有没有更好的?Top

13 楼microyzy(人不在牛,分高就行;分不在高,人牛也行)回复于 2001-11-20 17:59:58 得分 0

主要是某天没有记录得问题。Top

14 楼icevi(按钮工厂)回复于 2001-11-20 18:01:33 得分 0

假设表是这样的:  
  fdate,facctid,balance  
  并且期初余额在此表中有记录,且每天一个账户最多一条记录。并且不考虑日期不连续的问题,可以这样写:  
   
  select   t1.fdate,t2.facctid,  
            isnull(bal.balance,  
              (select   balance   from   bal   t3   where   facctid=t2.facctid   and    
                    fdate=(select   max(fdate)   from   bal   where   fdate<=t1.fdate))  
                )   as   balance  
  from   bal,  
            (select   distinct   fdate   from   bal)   t1   ,  
            (select   distinct   facctid   from   bal)   t2  
  where   bal.fdate=*t1.fdate   and   bal.facctid=*t2.facctid  
  order   by   t1.fdate,t2.facctid  
   
  MS出这样的题吗?这么不明确,有什么意思啊???  
   
   
  Top

15 楼leorb(◥银狐◣)回复于 2001-11-20 18:02:14 得分 0

to   icevi(按钮工厂)(女)  
  做存储过程?那花一百万追你也一定可以。。。  
  你多大啦Top

16 楼progame(www.progame.org)回复于 2001-11-20 18:02:28 得分 0

倒着算,可以实现,如果多条语句连接可以算一条语句的话  
  Top

17 楼microyzy(人不在牛,分高就行;分不在高,人牛也行)回复于 2001-11-20 18:04:26 得分 0

每天一个账号一般都不会只有一条记录了。  
  有可能没有记录,也有可能有多条记录。Top

18 楼harrypotter(哈里*波特)回复于 2001-11-20 18:09:51 得分 0

studyTop

19 楼icevi(按钮工厂)回复于 2001-11-20 18:11:42 得分 0

写错了:(  
  上面的语句改成:  
  select   t1.fdate,t2.facctid,  
        isnull(bal.balance,  
        (select   balance   from   bal   t3   where   facctid=t2.facctid   and    
        fdate=(select   max(fdate)   from   bal   t4   where   t4.facctid=t2.facctid   and   fdate<=t1.fdate)))   as   balance  
  from   bal,  
        (select   distinct   fdate   from   bal)   t1   ,  
        (select   distinct   facctid   from   bal)   t2  
  where   bal.fdate=*t1.fdate   and   bal.facctid=*t2.facctid  
  order   by   t1.fdate,t2.facctidTop

20 楼supine(懒人)回复于 2001-11-20 18:12:17 得分 0

按microyzy(毛毛叉)的表结构:  
  select   min(余额),[账号],max(时间n)   from   表   group   by   时间,账号  
   
  Top

21 楼icevi(按钮工厂)回复于 2001-11-20 18:14:19 得分 0

不过就算是一天一个账户有多条记录,也可以用查询生成一个一天只有一条记录的表,再嵌套进去就行了。  
  Top

22 楼foolflyfish(I am progame.)回复于 2001-11-20 18:16:41 得分 0

忙。。。。。  
   
  如果建表的时候就加入余额就方便了,但不符合数据库设计的规范了Top

23 楼microyzy(人不在牛,分高就行;分不在高,人牛也行)回复于 2001-11-20 18:17:09 得分 0

请教:supine(懒人)  
  为什么要用   max()?  
  并且还是解决不了账号某一天没有支出得情况。Top

24 楼hydnoahark(诺亚方舟)回复于 2001-11-20 18:18:27 得分 0

CREATE   TABLE   [dbo].[TABLE2]   (  
  [username]   [varchar]   (50)   NOT   NULL   ,   --用户名  
  [outdate]   [datetime]   NOT   NULL   ,   --日期  
  [cash]   [float]   NOT   NULL   --余额  
  )   ON   [PRIMARY]  
   
  由于每天每个用户可能有多条纪录,我们需要用户每天余额最小的那条纪录:  
  select   username,outdate,min(cash)   from   table2    
  group   by   outdate,username  
  order   by   outdate,usernameTop

25 楼supine(懒人)回复于 2001-11-20 18:18:36 得分 0

很有可能每天不止一条记录,而且有些天没有记录。最好是如果有当天记录,就取当天记录的最小值(因为他说是如果有支出才增加一条记录,所以余额是不断减少的),如果没有则取改天以前的最小余额!Top

26 楼supine(懒人)回复于 2001-11-20 18:22:46 得分 0

怎样对付某些天没有记录的情况?Top

27 楼hydnoahark(诺亚方舟)回复于 2001-11-20 18:29:32 得分 0

是个问题,100天中可能有很多天都是没有纪录的。  
  Thinking...Top

28 楼leorb(◥银狐◣)回复于 2001-11-20 18:30:50 得分 0

对,如果有一天没有任何帐户支出,那怎样才能查询出该天各个账户的余额。。。Top

29 楼foolflyfish(I am progame.)回复于 2001-11-20 18:32:19 得分 0

要用游标了,否则我想不出办法了,搬个板凳坐在一旁看..............Top

30 楼leorb(◥银狐◣)回复于 2001-11-20 18:37:45 得分 0

关键是怎样产生一百天内完整的日期。。。  
  icevi(按钮工厂)(女)   你不是说可以查询生成吗,SQL呢Top

31 楼progame(www.progame.org)回复于 2001-11-20 18:42:32 得分 0

能不能这样啊select   IDENTITY(smallint,   1,   1)   AS   id,DATEADD(day,   id,   minoutdate)  
   
    as     outdate   ..................Top

32 楼IronPromises(铁诺)回复于 2001-11-20 18:49:18 得分 0

 
  IDENTITY函数只能在  
  Select   into语句中用.  
   
  Top

33 楼progame(www.progame.org)回复于 2001-11-20 18:51:12 得分 0

思考中。。。Top

34 楼progame(www.progame.org)回复于 2001-11-20 18:52:49 得分 0

思考中。。。Top

35 楼redseashan(redseashan)回复于 2001-11-20 18:53:02 得分 0

用一个表保存每天的日期,用Job对象在每天23:59秒里插入一条数据,以这个日期表为驱动表,运用left   Join   和   decode()(this   is   oracle   Function,   I   think   MS   has   this   function   function   too),再加上group   by   ,应该能解决这个问题。Top

36 楼supine(懒人)回复于 2001-11-20 18:55:33 得分 0

现在是些用sql表达问题,如果用程序或过程,什么都可以实现他Top

37 楼leorb(◥银狐◣)回复于 2001-11-20 18:58:41 得分 0

select   查询.日期,账户,  
      (  
      select   min(金额)  
      from   表名  
      where   账户=别名.账户   and   日期   between   一百天前   and   查询.日期  
      )   余额  
  from   (progame的查询)   查询,表名   别名  
  where   查询.日期=别名.日期(+)   and   查询.日期   between   一百天前   and   一百天后  
  order   by   查询.日期,账户  
  group   by   查询.日期,账户  
  如果progame的查询可以的话,这样应该也行。。。Top

38 楼redseashan(redseashan)回复于 2001-11-20 18:58:51 得分 0

忘了一个min()   functionTop

39 楼progame(www.progame.org)回复于 2001-11-20 18:58:54 得分 0

掉发中。。。Top

40 楼progame(www.progame.org)回复于 2001-11-20 18:59:47 得分 0

我的不行啊:(Top

41 楼progame(www.progame.org)回复于 2001-11-20 19:00:04 得分 0

秃发中。。。Top

42 楼icevi(按钮工厂)回复于 2001-11-20 19:03:27 得分 0

一条语句应该不行,象   progame   说的,用identity可以做的,但是要生成临时表才行:  
  假设从2001-10-1开始  
  select   top   100   identity(int,1,1)     as   id   into   #temp   from   bal    
   
  select   t1.fdate,t2.facctid,  
      isnull(bal.balance,  
      (select   balance   from   bal   t3   where   facctid=t2.facctid   and    
      fdate=(select   max(fdate)   from   bal   t4   where   t4.facctid=t2.facctid   and   fdate<=t1.fdate)))   as   balance  
  from   bal,  
      (select   cast(id+cast('2001-10-1'   as   int)-1   as   datetime)   as     fdate   from   #temp)   t1   ,  
      (select   distinct   facctid   from   bal)   t2  
  where   bal.fdate=*t1.fdate   and   bal.facctid=*t2.facctid  
  order   by   t1.fdate,t2.facctid    
  Top

43 楼progame(www.progame.org)回复于 2001-11-20 19:06:42 得分 0

按钮,如果bal中没有100条记录呢?Top

44 楼leorb(◥银狐◣)回复于 2001-11-20 19:08:29 得分 0

progame的查询,用Oracle可以这样  
  Select   日期+RowNum   From   (Select   Distinct   帐号   From   表名);Top

45 楼icevi(按钮工厂)回复于 2001-11-20 19:11:12 得分 0

progame:肯定有100条记录的,因为有100个账户的期初余额啊!Top

46 楼progame(www.progame.org)回复于 2001-11-20 19:13:43 得分 0

那如果说100个账户1000天的余额呢Top

47 楼leorb(◥银狐◣)回复于 2001-11-20 19:20:09 得分 0

大不了。。。  
  (Select   日期1)  
  Union  
  (Select   日期2)  
  Union  
  (Select   日期3)  
  Union  
  (Select   日期4)  
  。。。  
  一万天,我就一万个,哈哈。。。  
   
  Top

48 楼progame(www.progame.org)回复于 2001-11-20 19:23:02 得分 0

我也这样想过,不过无赖了一些:)Top

49 楼leorb(◥银狐◣)回复于 2001-11-20 19:23:15 得分 0

用Union产生数据,Cool。。。Top

50 楼icevi(按钮工厂)回复于 2001-11-20 19:23:24 得分 0

哈哈。。。。  
  题目就这么出的,你不觉得两个一百很奇怪吗?  
   
  若是要1000天的,也可以啊。就是要再多几条语句了:(  
   
  MS出这样题?!真是刁钻!  
   
  Top

51 楼supine(懒人)回复于 2001-11-20 19:24:16 得分 0

这个主意不错,谁有空谁写来看看Top

52 楼leorb(◥银狐◣)回复于 2001-11-20 19:25:45 得分 0

Oracle我是搞定了,SQL   Server你们想。。。Top

53 楼progame(www.progame.org)回复于 2001-11-20 19:26:39 得分 0

OK,不去管它了,忙着呢。。。。。  
   
  Top

54 楼Haiwer(海阔天空)回复于 2001-11-20 19:50:14 得分 0

  你们讨论那么久,结果也有了,可以用一条语句实现,但是,题目里没有说要用一条语句?Top

55 楼llzczf(流浪汉)回复于 2001-11-20 20:30:22 得分 0

这个问题,不难呀,建两个表一个过程表,一个结果表,每天支出的记录放入过程表里,然后UPDATE结果表,不就搞定么,结果表里放的总是余额。  
  Top

56 楼htw(htw)回复于 2001-11-20 20:47:38 得分 0

微软会出这种简单的题吗?   真是奇怪!Top

57 楼progame(www.progame.org)回复于 2001-11-20 20:55:48 得分 0

都没看清题目Top

58 楼mmzxg(超级笨蛋)回复于 2001-11-21 09:34:56 得分 0

利用两个表,再利用触发器,一个结果表(统计余额),一个过程表(记录各条发生金额,其中用触发器,对发生额计算)  
   
  我不单是个笨蛋,而且是个超级笨蛋  
   
  况且,MS的要求到底是什么呢,有没表格限制呢????Top

59 楼dudo(dudo)回复于 2001-11-21 11:57:35 得分 0

select   客户名称,convert(varchar(10),日期,120)   AS   日期,min(余额)   as   余额   from   TABLE1  
  group   by   客户名称,convert(varchar(10),日期,120)  
  Top

60 楼jassonlu(虾米)回复于 2001-11-21 12:32:46 得分 0

原理是:将每个帐户每天的最后一条记录显示出来即可,如果该帐户该天没有记录,则使用上一天的结果记录。应该一条语句就OK了。  
  Top

61 楼touhu(虾仔)回复于 2001-11-21 12:57:37 得分 0

不是吧,微软的面试题就这么简单啊Top

62 楼fatpig521(瘦驼)回复于 2001-11-21 12:58:23 得分 0

我感觉,题目并不简单。  
  要求是每个账户日期是连续的,事实上可能是间断的。关于余额到是相对简单些。Top

63 楼lbpb(新年快乐)回复于 2001-11-21 13:07:46 得分 0

一百个账户各有100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后,请输出每天所有账户的余额信息Top

64 楼bisc_sunny(总是当时携手处,游遍芳丛)回复于 2001-11-21 14:05:54 得分 0

有什么难的。  
  需求是需要记录每一次的存取,并根据每一次的存取计算总和。  
   
  ID:   Identyfy   Int   /Primary   Key  
  SN:   Varchar(50)   /Account   SN  
  Money   :Bigint   /Money   Left  
  Date:   DateTime   /Account   Date  
   
  Select  
      SN,  
      Money,  
      Date   as   [Last   Account   Date]    
  From   Table  
      Where   ID   =   (Select   ID   From   Table   as   A    
                                  Where   A.Date   =   (Select   Max(Date)   From   Table   as   B  
                                                                    Where   B.SN   =   A.SN   )  
                                  and       A.SN   =   Table.SN)  
   
  Top

65 楼bisc_sunny(总是当时携手处,游遍芳丛)回复于 2001-11-21 14:12:59 得分 0

对不起看错了,这是最后的余额。正在想...Top

66 楼crazymens(风)回复于 2001-11-21 14:14:29 得分 0

1、表结构       :建立两个表,一个存放用户名和余额,如果某日进行操作,则该日有一条纪录(不管该日有多少次交易,余额应该总是反映最后一次交易的余额)   ;另外一个表是交易名细,可能正,可能负数   ,里面还应该存放交易操作原因(最好将交易操作原因单独建立一个表   。)对这个表建立存储过程,让它在更新的同时自动更新余额表   。  
   
  2、报表显示   :在客户方处理报表很灵活了,方法很多   。在服务器方生成报表要用到游标,用游标存放用用户名称,然后建立一个计数器,从0到100循环(在while循环中),然后用DateAdd可以计算出具体的日期   ,然后找到那个日期某个用户的余额   。由于用户不是每天都发生交易,所以对于那些没有交易的日子余额标中就没有纪录,这时候要特殊处理一下。  
   
   
  个人意见,不知道是否可行,这样做效率如何,希望大家指正   。    
   
    Top

67 楼bluemeteor(挂月||Becoder)回复于 2001-11-21 14:35:14 得分 0

如果某一天没有支出那么实际上那天的余额应该是上一天的,但是表中却没有这一天的记录,怎么查?  
  Top

68 楼KingSunSha(弱水三千)回复于 2001-11-21 14:48:06 得分 0

强烈要求贴主公布MS的答案!!!!  
   
  我倒想看看有什么好方法Top

69 楼panjin1(panjin1)回复于 2001-11-21 15:15:42 得分 0

其实很简单:  
  建一个表TableAccount.  
  字段名           意义  
  AccCode         帐户代码  
  TranDare       业务发生日期  
  TranNum         业务流水号  
  TranCode       业务类别代码(1:为收入;-1:为支出)  
  TranMoney     业务金额  
   
  SQL语句应该不复杂。Top

70 楼yanghui88(pig)回复于 2001-11-21 15:20:19 得分 0

你放"噗",  
  不复杂,你来试试.  
  题目都没看清楚,乱发飙.Top

71 楼jasmine(Yaya)回复于 2001-11-21 15:22:52 得分 0

不要求每天都打出来,大家都会做,如果要求每天打出来,我能想到是给没有的天或账号补0,然后再查询计算,我想不出很简单的方法,看答案!Top

72 楼N_chow(Yukon)回复于 2001-11-21 15:31:31 得分 0

哇拷!人气巨旺。Top

73 楼mmzxg(超级笨蛋)回复于 2001-11-21 15:44:46 得分 0

强劲,厉害。。。。。。。Top

74 楼zhangzy(海逗)回复于 2001-11-21 15:49:29 得分 0

建立一个表(金额,时间(日期+发生时间),资金账号);  
   
  select   *   from   tablename   where   时间=(select   max(时间)from   tablename   group   by   资金账号)  
  Top

75 楼MountLion(闷头睡)回复于 2001-11-21 15:52:29 得分 0

给programe的建议:  
      你的《XX必读》增加一条:  
      10.微软考试题,大家快来看Top

76 楼jilongge(果子)回复于 2001-11-21 16:22:59 得分 0

这是我同事于微软合作前所碰到的面试题。Top

77 楼N_chow(Yukon)回复于 2001-11-21 16:34:38 得分 0

該是時候公布答案了吧?!Top

78 楼liu_nan(柳南)回复于 2001-11-21 16:46:34 得分 0

很简单的面试题,在我的程序中经常会用到,方法很多,关键是怎么才能提高查询(历史记录,余额)速度Top

79 楼dephi(四眼田鸡)回复于 2001-11-21 16:53:01 得分 0

有难度  
  我也低头了  
  公布答案吧  
  Top

80 楼fallstone(天蓝)回复于 2001-11-21 16:53:45 得分 0

这个问题很能体现水平我觉得。Top

81 楼feifei2001(鼠标)回复于 2001-11-21 16:54:42 得分 0

基本思想是这样的:应该有至少两个表:资金表和资金流水。按时间记录下每一个帐号的流水,  
  最后可以联合查询,就可以了。  
   
   
  Top

82 楼Haiwer(海阔天空)回复于 2001-11-21 17:02:24 得分 0

关键在于"每天所有账户的余额信息"中的"每天的余额",上面讨论已经有方法!  
   
  但不知道标准答案!Top

83 楼Jack_Loo(Jack Loo)回复于 2001-11-21 17:38:13 得分 0

2个表,一个是主表,一个是余额表,即可。Top

84 楼Jack_Loo(Jack Loo)回复于 2001-11-21 17:40:37 得分 0

说错了,不是余额表,应该是历史表。余额字段在主表里。Top

85 楼N_chow(Yukon)回复于 2001-11-21 17:54:18 得分 0

這道題自由發揮的空間蠻大呀,又沒有限制說用一條語句、用一個表來完成。  
  其實我覺得用Jack_Loo(Jack   Loo)的方法蠻好的。歷史表里存每天的支出信息。  
   
   
  Top

86 楼PBVC(圆砣)回复于 2001-11-21 23:59:43 得分 0

标准答案出来了没  
   
  标准答案出来了没  
   
  标准答案出来了没  
   
  标准答案出来了没  
   
  标准答案出来了没Top

87 楼phoenix33(阳光)回复于 2001-11-22 00:26:19 得分 0

假如一个用户1天内有几次支出,是取最后那次,还是全取出来!!!!Top

88 楼nononono(null,null)回复于 2001-11-22 01:16:27 得分 0

按题意做如下假设:  
  表table1(代码   char(10),   日期   datetime,   金额   int)期初有100条记录,   各账户只发生支出(即金额只能减少),   允许一日内有多笔支出.   要求列出一百天各天的余额,   即结果应该有100*100条记录.  
  题目没有要求只用一条SQL语句.  
  Top

89 楼qwm(土豆)回复于 2001-11-22 01:41:35 得分 0

看了这个题有点意思提一个想法供大家参考!  
  分析:本题解决方向我认为在于把账户和天数这种二维关系简化成一维关系,  
  便于SQL的查询!  
  一建表  
  CREATE   TABLE   abc(  
  [querytemp]   [varchar]   (50),'查询临时中间字段无实际意义但在后边用得着!  
  [username]   [varchar]   (50)   NOT   NULL   ,   --用户名  
  [tdate]   [datetime]   NOT   NULL   ,   --日期  
  [cash]   [float]   NOT   NULL   --余额  
  )   ON   [PRIMARY]  
  ***插入记录说明:  
  当有余额发生时,取当日日期并把它转化成STRING,插入时放入querytemp字段中这很重要!  
  二查询  
  select   *(sum也行)   from     abc   where   (日期夹板)   group   by   querytemp  
  SQL简写了,这样每天的余额被分组查询出来!  
  ----END  
  欢迎交流!  
  E_MAIL:   QWM123@163.NET  
  Top

90 楼nononono(null,null)回复于 2001-11-22 01:57:38 得分 0

我抛砖引玉,   给出我的算法.   结果是100*100条记录,   没有期初记录,   如果需要可略改之.   算法显得笨拙,   给各位开开心.   呵呵  
   
  如果代码的个数是30,   则会得到30天内的每日余额,   即30*30个记录.  
   
   
  declare   @最早日期   datetime  
   
  select   @最早日期=min(日期)   from   table1  
   
  select   IDENTITY(int,   1,   1)   as   天数   into   #temp1   from   table1   where   convert(char(10),日期,120)=convert(char(10),@最早日期,120)  
   
  create   table   #temp2   (代码   char(10),   日期   datetime,   余额   int)  
   
  insert   into   #temp2   (代码,   日期)    
        select   table1.代码,   DATEADD(dd,#temp1.天数   ,table1.日期)    
              from   #temp1,   table1    
              where   convert(char(10),table1.日期,120)=convert(char(10),@最早日期,120)  
   
  update   #temp2    
        set   余额=(select   min(金额)    
                                    from   table1    
                                    where   table1.代码=#temp2.代码   and    
                                                convert(char(10),table1.日期,120)<=convert(char(10),#temp2.日期,120)  
                          )  
   
  select   *   from   #temp2  
   
  drop   table   #temp1  
   
  drop   table   #temp2  
  Top

91 楼nononono(null,null)回复于 2001-11-22 02:24:15 得分 0

上面的#temp2可以省略,   不过省略的效果并不好.   算法,   以简单明了为最好!Top

92 楼fatpig521(瘦驼)回复于 2001-11-22 09:10:56 得分 0

我觉得你可以,先尝试一下只有一个账户时,100天之内有不连续的少数次支出的情况。  
  例如:第一天,第50天各支出10。试着选出连续100天余额结果?Top

93 楼nononono(null,null)回复于 2001-11-22 09:27:41 得分 0

不连续的支出,   一日内多笔支出,   最后得到100天连续的余额,   最后得到每客户每日一条余额记录.    
   
  就是这样.  
  Top

94 楼legenx(legenx)回复于 2001-11-22 09:55:01 得分 0

来点高深一点的:  
  现在要求输出成如下,谁有办法?  
   
  日期,帐号1余额,帐号2余额,帐号3余额,帐号4余额,......帐号100余额  
   
  Top

95 楼yanuser(yanuser)回复于 2001-11-22 10:20:32 得分 0

当然可以:  
  Table   fields:   流水号,   账户,日期,余额  
   
  select   distinct   日期,  
  (select   min(B.余额)   from   B   where   B.日期=A.日期   and   B.账户=A.账户)as   帐号1余额,()   as   帐号2余额,......   ()   as   帐号100余额    
  from   table   as   A    
  order   by   日期  
  Top

96 楼yanuser(yanuser)回复于 2001-11-22 10:21:54 得分 0

当然,上面是最苯的方法Top

97 楼cm_locke(□×○△)回复于 2001-11-22 10:59:59 得分 0

最容易的方法!呵呵……  
  select   帐号,min(余额)   from   表   group   by   帐号  
  搞掂……呵呵!  
  说好是支出,当然是余额越来越少拉,这样一条语句搞点!呵呵Top

98 楼icevi(按钮工厂)回复于 2001-11-22 11:10:12 得分 0

不确定的东西太多了。我想可能也没有什么标准答案。毕竟表记录是怎么样的,题目中并没有说明。  
  Top

99 楼mars_bolt(火箭炮)回复于 2001-11-22 11:40:31 得分 0

快公布答案,如果有的话。  
  要不然下回我也出个Ms.的面试题。Top

100 楼Haiwer(海阔天空)回复于 2001-11-22 12:02:58 得分 0

呵呵,到100了,nononono(null,null)的方法挺好! Top

101 楼tom255(吸血鬼)回复于 2001-11-22 13:36:59 得分 0

建3个表,1当前余额,2每日余额,3每笔交易,  
   
  trans  
  操作3触发2减去交易额(如果没有当日记录,添加),同时触发1减去交易额  
  commit  
  Top

102 楼jilongge(果子)回复于 2001-11-22 14:06:12 得分 0

这道题我也不知道答案,只是拿出来大家一块研究研究,不过绝对保证是微软面试题!!Top

103 楼mashansj(风影)回复于 2001-11-22 14:30:47 得分 0

这里的支出肯定是有正有负,即余额不一定是越来越少的Top

104 楼mashansj(风影)回复于 2001-11-22 14:39:42 得分 0

表(账户,余额,时间)  
  select   账户,余额  
  from   table  
  where   time=max(time)  
  order   by   账户;  
   
   
  Top

105 楼mashansj(风影)回复于 2001-11-22 14:41:14 得分 0

group   by   账户;Top

106 楼jerry_baimor(崇拜starfish)回复于 2001-11-22 14:55:42 得分 0

拜托把题目说清楚,  
  每天若有取款发生,那么就“插入”,那么一个relation   will   explode   to   infinite   size.  
  这这么可以?  
  Top

107 楼jilongge(果子)回复于 2001-11-22 15:09:16 得分 0

这道题就是一个需求怎么分析都看你自己的设想,不要总是说缺这个少那个的。  
  什么时候需求都不是固定的Top

108 楼lxinjun(lxj)回复于 2001-11-22 15:11:29 得分 0

可以建立一个引擎,补充那些某天没有支出的帐户,  
  然后  
  select   日期,账户,min(金额)   as   余额  
  from   表   别名  
  where   (账户+金额   in   (sele   账户+min(金额)   from   别名   group   by   日期,账户))  
  and   日期   between   一百天前   and   现在    
  order   by   日期,账户  
  group   by   日期,账户  
     
  Top

109 楼lvhy(虚无纠缠着存在)回复于 2001-11-22 15:23:05 得分 0

我觉得这样是对的  
   
  select   id,min(balance)   from   account   where   date<='yyyymmdd'   group   by   id  
   
  Top

110 楼mashansj(风影)回复于 2001-11-22 15:56:55 得分 0

表table(账户id,余额balance,时间time)  
   
  select   id,balance  
  from   table   a  
  where   a.time=(select   max(time)   from   table   b   where   a.id=b.id   and   a.balance=b.balance);  
   
  字段time作为唯一标识,即同一天多笔业务time不同     Top

111 楼linhu(林胡冲)回复于 2001-11-22 15:57:40 得分 0

我实现了,不过不是一条语句,谁要请举手示意我。Top

112 楼Haiwer(海阔天空)回复于 2001-11-22 16:00:13 得分 0

那你可以微软了!Top

113 楼Haiwer(海阔天空)回复于 2001-11-22 16:01:29 得分 0

那你可以去微软了  
   
  对不起,漏了一个字.Top

114 楼mashansj(风影)回复于 2001-11-22 16:01:38 得分 0

各位有何意见?Top

115 楼zzllabc(抱朴子--清心释累,绝率忘情)回复于 2001-11-22 16:45:47 得分 0

用一个表保存每天的日期,用Job对象在每天23:59秒里插入一条数据,以这个日期表为驱动表,运用left   Join   和   decode()(this   is   oracle   Function,   I   think   MS   has   this   function   function   too),再加上group   by   ,应该能解决这个问题。Top

116 楼Nee(土货)回复于 2001-11-22 16:46:07 得分 0

SELECT   TOP   1000   *  
  FROM   表  
  WHERE   帐号="按钮MM"   AND   时间<=想要的日期  
  ORDER   BY   时间   DESC  
   
  这样可以取得一个用户指定日期的余额记录  
   
  然后就扩充就行了Top

117 楼Nee(土货)回复于 2001-11-22 16:48:15 得分 0

不好意思,是“TOP   1”Top

118 楼371(371)回复于 2001-11-22 18:07:40 得分 0

建立两个表:  
  结构:[userbalance]   每天消费余额  
  id                       自动记录     int  
  myuser               账户             varchar  
  balance             余额             money  
  dateandtime     日期             datetime  
  [balance]记录账户最后余额  
  id                       自动记录     int  
  myuser               账户             varchar  
  balance             余额             money  
   
  “输出每天所有账户的余额信息”,不知道是每人每天的消费记录只输出最后一条还是输出当天的全部消费记录。  
  如果是只输出最后一条,可以建立这样一条消费机制:  
      消费发生时候,从[]取出账户和余额,经过扣除,查询[]中的记录,没有该帐户当天消费记录,插入记录;有当天记录,更新该记录。最后选取。  
  如果是当天的全部消费记录,按照上一个办法,只是不覆盖前一条记录,最后按照日期和用户帐号分组选取。  
  Top

119 楼371(371)回复于 2001-11-22 18:09:09 得分 0

补充更正:第一个[]是[balance],第二个是[userbalance]Top

120 楼hssfox()回复于 2001-11-22 18:35:53 得分 0

看看  
  Top

121 楼371(371)回复于 2001-11-22 19:39:18 得分 0

第一种方法的储存过程:  
  (由于时间限制,在“where   (day(dateandtime)   =   day(@buy_date)”有一个漏洞,没能就时间的精确比较更多的考虑,但大意如此了。哪位仁兄补充一下了。但试运行了,可以满足要求。)  
  --  
  CREATE   TABLE   [balance]   (  
  [id]   [int]   IDENTITY   (1,   1)   NOT   NULL   ,  
  [myuser]   [varchar]   (50)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL   ,  
  [balance]   [money]   NOT   NULL    
  )   ON   [PRIMARY]  
  GO  
  CREATE   TABLE   [mybalance]   (  
  [id]   [int]   IDENTITY   (1,   1)   NOT   NULL   ,  
  [myuser]   [varchar]   (50)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL   ,  
  [banlance]   [money]   NOT   NULL   ,  
  [dateandtime]   [varchar]   (50)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL    
  )   ON   [PRIMARY]  
  GO  
  --  
   
   
  if   exists(select   *   from   sysobjects   where   id   =   object_id('buy'))  
        drop   proc   buy  
  go  
   
  create   proc   buy  
   
    @buycount   money,  
    @buy_myuser   varchar,  
    @buy_date       smalldatetime  
  as  
        declare   @nowcount   money  
      if     exists(select   *   from   balance   where   myuser   =   @buy_myuser)  
        begin  
        select   @nowcount   =   [balance]   from   balance   where   myuser   =   @buy_myuser  
        select   @nowcount   =   @nowcount   -   @buycount  
      end  
      else  
      begin  
      return  
      end  
                  if     exists(select   *   from   mybalance   where   (day(dateandtime)   =   day(@buy_date))  
                  and   (myuser   =   @buy_myuser))    
                    begin  
                    update   mybalance   set   banlance   =   @nowcount   where   (day(dateandtime)   =   day(@buy_date)  
                    and   (myuser   =   @buy_myuser)   )  
                    update   balance   set   balance   =   @nowcount   where   myuser   =   @buy_myuser  
                    end      
                  else  
                      begin  
                      insert   into   mybalance   (myuser,banlance,dateandtime)    
                      values   (@buy_myuser,@nowcount,@buy_date)    
                      update   balance   set   balance   =   @nowcount   where   myuser   =   @buy_myuser  
                      end  
   
  go  
  ------消费  
  exec   buy   1,'b'   ,'2001-11-22   16:00:00'  
  ------最后统计  
  select   *   from   mybalanceTop

122 楼amsea(笑容)回复于 2001-11-22 19:41:10 得分 0

欢迎没有工作的高手来我这里啊~!  
  http://www.csdn.net/expert/topic/383/383775.shtmTop

123 楼EdwinYeah(Edwin)回复于 2001-11-22 20:13:27 得分 0

面试题?Top

124 楼abc229(泡泡龙)回复于 2001-11-22 20:36:30 得分 0

我有答案了(经过测试)  
  create   table   test_sql(account   varchar(20),paydate   varchar(20),balance   decimal(10,2));  
  create   table   test_date(seqdate   varchar(20));  
  向test_date内插要查询的100天  
  select   x.account,x.seqdate,min(balance)   from  
  (select   *   from   (select   distinct   account   from   test_sql)   a,   test_date   b   )   x,test_sql   y  
  where   x.account   =   y.account   and   x.seqdate   >=   y.paydate  
  group   by   x.account,x.seqdate  
  解释:先用account,seqdate交叉形成每个帐号每日的记录,然后用seqdate>=paydate关连,  
  再从中选取最小的balance(注意,本题中只有支出!)  
  Top

125 楼blackfiles(一个和尚挑水喝)回复于 2001-11-22 21:35:45 得分 0

没有标准么?Top

126 楼kyosing(火)回复于 2001-11-22 23:09:02 得分 0

没什么的!  
  Top

127 楼bucher(无人永生)回复于 2001-11-23 00:01:17 得分 0

我觉得如果没有限制的话使用一个ScheduleJob每天往数据表里面写入当天余额即可。  
  如果不能这样做我比较倾向于使用临时表,不太喜欢使用游标。  
  我觉得楼上的算法有一些问题,如果某一天一个账户也没有支出那么你的结果就会少一条纪录。Top

128 楼solomon(金矿)回复于 2001-11-23 10:46:33 得分 0

请看:题目如下  
  一百个账户各有100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后,请输出每天所有账户的余额信息。  
  条件:   1.   100   个帐户,   (意思:初值相同)  
                2.   某天如有支出则添加一条新记录  
                      (意思,   a.   只有减少,   b.   每天每个帐户最多只增加一条记录)  
                3.   一百天后   (意思:一共要输出   一万(100*100   )条记录)  
                4.   输出可能是  
  日期     帐户     余额  
  1           1           100  
  1           2           100  
  .......  
  100       1           0  
  100       2           90  
  .....  
  100       100       50  
   
  关键:   100   天,   100   个帐户  
  一句SQL   搞定.   答案暂时不公布。  
  (好像有点脑筋急转弯的意思?)  
   
  Top

129 楼liu7537(数据库模型设计博客连载(http://blog.csdn.net/liu7537))回复于 2001-11-23 11:36:25 得分 0

这个问题需要用到关联子查询。  
  设表accounts为账户表,details表为有支出则插入新记录的表。  
  select   a.AcountID,a.AcountName,min(d.balance)   from   account   as   a,details   d   where   d.AcountID=(select   AcountID   from   details   where   d.AcountID=a.AcountID)Top

130 楼nononono(null,null)回复于 2001-11-23 11:36:39 得分 0

solomon的假设可以接近1句SQL语句了,   不过需要明确一点:   字段"帐户"的类型应该是int,   并且是1..100的.   如此,   1句可以搞定.Top

131 楼abc229(泡泡龙)回复于 2001-11-23 11:43:09 得分 0

大家有没有看清我的答案呢?  
  用帐号和日期交叉自然形成了100个帐号100个日期的结果集,再用seqdate>=paydate关连  
  此数据表,然后从中选择唯一的帐号、日期和最小的余额。  
  不对吗?Top

132 楼nononono(null,null)回复于 2001-11-23 12:03:43 得分 0

abc229(泡泡龙),   "向test_date内插要查询的100天",   你怎么做的?   是预先做好的吗?Top

133 楼abc229(泡泡龙)回复于 2001-11-23 14:30:20 得分 0

是啊,没说不允许啊!Top

134 楼abc229(泡泡龙)回复于 2001-11-23 15:11:31 得分 0

我有答案了(经过测试)  
  create   table   test_sql(account   varchar(20),paydate   varchar(20),balance   decimal(10,2));  
  create   table   test_date(seqdate   varchar(20));  
  向test_date内插要查询的100天  
  select   x.account,x.seqdate,min(balance)   from  
  (select   *   from   (select   distinct   account   from   test_sql)   a,   test_date   b   )   x,test_sql   y  
  where   x.account   =   y.account   and   x.seqdate   >=   y.paydate  
  group   by   x.account,x.seqdate  
  解释:先用account,seqdate交叉形成每个帐号每日的记录,然后用seqdate>=paydate关连,  
  再从中选取最小的balance(注意,本题中只有支出!)  
  Top

135 楼juqiang(方枪枪(正在修炼伤心小箭))回复于 2001-11-23 15:34:12 得分 0

study!!!Top

136 楼pingguo(e网情深)回复于 2001-11-23 16:19:35 得分 0

太难了!头都晕了。Top

137 楼charlce()回复于 2001-11-23 17:24:02 得分 0

帐户使用表:Account(id,leave_m--余额,days--日期,account_id--帐号)  
  帐号表:Account_n(account_id--帐号)  
  结果表:a2(leave_m--余额,days--日期,account_id--帐号)  
  生成存储过程Cal_Account:  
  create   procedure   Cal_account   as  
  declare   @i   int--距今天的天数  
  declare   @am   int--用于记录每日帐户余额  
  declare   @ds   datetime--记录日期  
  declare   @Temp_id   int--用于对每个帐号进行循环;  
  select   @i=100  
  while   @i>0  
  begin  
  Select   @ds=str(year(getdate()-@i),4)+'-'+str(month(getdate()-@i),2)+'-'+str(day(getdate()-@i),2)  
  Declare   Accountid   Cursor     SCROLL     For   Select   name_id   From     account_n  
  Open   Accountid  
  Fetch   First   From   Accountid   into   @Temp_id  
  While   (@@fetch_status=0)--开始计算每个帐号每天的最终记录  
  Begin  
    if   Exists(select   *     from   account   where   datediff(d,days,getdate())=@i   and   account_id=@Temp_id)  
  Select   @am=min(leave_m)   from   account   where   datediff(d,days,getdate())=@i   and   account_id=@Temp_id    
  else  
  Select   @am=min(leave_m)   from   a2   where   datediff(d,days,getdate())=(@i+1)   and   account_id=@Temp_id    
  insert   into   a2   values(@am,@ds,@Temp_id)  
    fetch   Next   from   Accountid   into   @Temp_id  
  End    
  Deallocate   Accountid  
  select   @i=@i-1  
  continue  
  End  
   
   
  然后运行该存储过程,最后查看表a2,既是结果Top

138 楼charlce()回复于 2001-11-23 17:29:15 得分 0

jilongge,我的可以得分吗??/?Top

139 楼linhu(林胡冲)回复于 2001-11-23 17:30:31 得分 0

一句Sql!不可能吧?Top

140 楼whoiswho(中文字符)回复于 2001-11-23 17:52:02 得分 0

关键是怎么处理没有数据记录的那天的余额,Top

141 楼charlce()回复于 2001-11-23 17:57:30 得分 0

我的已经处理了Top

142 楼abc229(泡泡龙)回复于 2001-11-23 18:04:12 得分 0

看看我的SQL吧!  
  Top

143 楼ghkong(辉云散人)回复于 2001-11-23 18:05:32 得分 0

太简单了  
  表:id,帐号,name,余额,日期  
  一百天后  
  select   name,帐号,日期,余额   from   表  
  where   datediff(day,起始日,结束日)   =   100  
  ok!Top

144 楼jilongge(果子)回复于 2001-11-23 18:13:48 得分 0

答对的别着急,看别人有没有更好的答案!!!Top

145 楼xwyliu(大象)回复于 2001-11-23 18:26:00 得分 0

too   simplede.Top

146 楼hydnoahark(诺亚方舟)回复于 2001-11-23 20:39:09 得分 0

一句搞定:  
  CREATE   TABLE   [dbo].[TABLE2]   (  
  [username]   [varchar]   (50)   NOT   NULL   ,   --用户名  
  [outdate]   [datetime]   NOT   NULL   ,   --日期  
  [cash]   [float]   NOT   NULL   --余额  
  )   ON   [PRIMARY  
   
  declare   @i   int  
  set   @i=1  
  while   @i<=100  
      begin  
          insert   table2   values(convert(varchar(50),@i),'2001-10-1',100)  
          insert   table2   values(convert(varchar(50),@i),'2001-11-1',50)  
          set   @i=@i+1  
      end  
  insert   table2   values(convert(varchar(50),@i),'2001-10-1',90)  
   
  select   *   from   table2   order   by   outdate,convert(int,username)  
   
   
  查询数据:  
  select   C.outdate,C.username,  
  case   isnull(D.cash,0)  
    when   0   then    
  (  
  select   top   1   cash   from   table2   where   table2.username=C.username  
  and   datediff(d,C.outdate,table2.outdate)<0    
  order   by   table2.cash  
  )  
    else   D.cash  
  end   as   cash  
  from  
  (  
  select   *   from  
  (  
  select   top   100   dateadd(d,convert(int,username)-1,min(outdate))   as   outdate  
  from   table2  
  group   by   username  
  order   by   convert(int,username)  
  )   as   A  
  CROSS   join    
  (  
  select   distinct   username   from   table2    
  )   as   B  
  )   as   C  
  left   join  
  (  
  select   outdate,username,min(cash)   as   cash   from   table2  
  group   by   outdate,username  
  )   as   D  
  on(C.username=D.username   and   datediff(d,C.outdate,D.outdate)=0)  
   
  order   by   C.outdate,convert(int,C.username)  
   
  返回结果:  
  outdate                 username                 cash  
  2001-10-1             1                               90  
  2001-10-1             2                               100  
  ......  
  2001-10-1             100                           100  
  ......  
  2001-10-2             1                               90  
  2001-10-2             2                               100  
  ......  
  2001-10-2             100                           100  
  .......  
  2001-10-31           100                           100  
  2001-11-1             1                               50  
  ......  
  2001-11-1             100                           50  
  ......  
  2002-1-8               100                           50Top

147 楼hydnoahark(诺亚方舟)回复于 2001-11-23 21:03:22 得分 0

对于SQL语句的说明:  
  1.创建表并插入测试数据:我们要求username从1-100  
  CREATE   TABLE   [dbo].[TABLE2]   (  
  [username]   [varchar]   (50)   NOT   NULL   ,   --用户名  
  [outdate]   [datetime]   NOT   NULL   ,   --日期  
  [cash]   [float]   NOT   NULL   --余额  
  )   ON   [PRIMARY  
   
  declare   @i   int  
  set   @i=1  
  while   @i<=100  
      begin  
          insert   table2   values(convert(varchar(50),@i),'2001-10-1',100)  
          insert   table2   values(convert(varchar(50),@i),'2001-11-1',50)  
          set   @i=@i+1  
      end  
  insert   table2   values(convert(varchar(50),@i),'2001-10-1',90)  
   
  select   *   from   table2   order   by   outdate,convert(int,username)  
   
  2.组合查询语句:  
  a.我们必须返回一个从第一天开始到100天的纪录集:  
  如:2001-10-1(这个日期是任意的)   到   2002-1-8  
  由于第一天是任意一天,所以我们需要下面的SQL语句:  
  select   top   100   dateadd(d,convert(int,username)-1,min(outdate))   as   outdate  
  from   table2  
  group   by   username  
  order   by   convert(int,username)  
  这里的奥妙在于:  
  convert(int,username)-1(记得我们指定用户名从1-100   :-))  
  group   by   username,min(outdate):第一天就可能每个用户有多个纪录。  
  返回的结果:  
  outdate                                                                                                  
  ------------------------------------------------------    
  2001-10-01   00:00:00.000  
  .........  
  2002-01-08   00:00:00.000  
   
  b.返回一个所有用户名的纪录集:  
  select   distinct   username   from   table2    
  返回结果:  
  username                                                                                        
  --------------------------------------------------    
  1  
  10  
  100  
  ......  
  99  
   
  c.返回一个100天记录集和100个用户记录集的笛卡尔集合:  
  select   *   from  
  (  
  select   top   100   dateadd(d,convert(int,username)-1,min(outdate))   as   outdate  
  from   table2  
  group   by   username  
  order   by   convert(int,username)  
  )   as   A  
  CROSS   join    
  (  
  select   distinct   username   from   table2    
  )   as   B  
  order   by   outdate,convert(int,username)  
  返回结果100*100条纪录:  
  outdate                                                         username  
  2001-10-01   00:00:00.000                         1  
  ......  
  2002-01-08   00:00:00.000                         100  
   
  d.返回当前所有用户在数据库的有的纪录:  
  select   outdate,username,min(cash)   as   cash   from   table2  
  group   by   outdate,username  
   
  order   by   outdate,convert(int,username)  
  返回纪录:  
  outdate                                                         username         cash  
  2001-10-01   00:00:00.000                         1                       90  
  ......  
  2002-01-08   00:00:00.000                         100                   50  
   
  e.将c中返回的笛卡尔集和d中返回的纪录做left   join:  
  select   C.outdate,C.username,  
  D.cash  
  from  
  (  
  select   *   from  
  (  
  select   top   100   dateadd(d,convert(int,username)-1,min(outdate))   as   outdate  
  from   table2  
  group   by   username  
  order   by   convert(int,username)  
  )   as   A  
  CROSS   join    
  (  
  select   distinct   username   from   table2    
  )   as   B  
  )   as   C  
  left   join  
  (  
  select   outdate,username,min(cash)   as   cash   from   table2  
  group   by   outdate,username  
  )   as   D  
  on(C.username=D.username   and   datediff(d,C.outdate,D.outdate)=0)  
   
  order   by   C.outdate,convert(int,C.username)  
  注意:用户在当天如果没有纪录,cash字段返回NULL,否则cash返回每个用户当天的余额  
  outdate                                                         username         cash  
  2001-10-01   00:00:00.000                         1                       90  
  2001-10-01   00:00:00.000                         2                       100  
  ......  
  2001-10-02   00:00:00.000                         1                       90  
  2001-10-02   00:00:00.000                         2                       NULL     <--注意这里  
  ......  
   
  2002-01-08   00:00:00.000                         100                   50  
   
  f.好了,现在我们最后要做的就是,如果cash为NULL,我们要返回小于当前纪录日期的第一个用户余额,这个余额即为当前的余额:  
  case   isnull(D.cash,0)  
    when   0   then    
  (  
  select   top   1   cash   from   table2   where   table2.username=C.username  
  and   datediff(d,C.outdate,table2.outdate)<0    
  order   by   table2.cash  
  )  
    else   D.cash  
  end   as   cash  
   
  g.最后组合的完整语句就是  
  select   C.outdate,C.username,  
  case   isnull(D.cash,0)  
    when   0   then    
  (  
  select   top   1   cash   from   table2   where   table2.username=C.username  
  and   datediff(d,C.outdate,table2.outdate)<0    
  order   by   table2.cash  
  )  
    else   D.cash  
  end   as   cash  
  from  
  (  
  select   *   from  
  (  
  select   top   100   dateadd(d,convert(int,username)-1,min(outdate))   as   outdate  
  from   table2  
  group   by   username  
  order   by   convert(int,username)  
  )   as   A  
  CROSS   join    
  (  
  select   distinct   username   from   table2    
  )   as   B  
  )   as   C  
  left   join  
  (  
  select   outdate,username,min(cash)   as   cash   from   table2  
  group   by   outdate,username  
  )   as   D  
  on(C.username=D.username   and   datediff(d,C.outdate,D.outdate)=0)  
   
  order   by   C.outdate,convert(int,C.username)  
   
   
   
   
  Top

148 楼hydnoahark(诺亚方舟)回复于 2001-11-23 21:10:00 得分 0

>>f.如果cash为NULL,我们要返回小于当前纪录日期的第一个用户余额,  
                                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  这里我可能有点没有说清楚,由于我们使用了order   by   cash,所以用top   1返回的纪录就是当前的余额,其实用min也是可以的Top

149 楼Go_Rush(我的技术博客http://ashun.cnblogs.com/)回复于 2001-11-23 21:18:27 得分 0

看看Top

150 楼abc229(泡泡龙)回复于 2001-11-23 21:35:38 得分 0

我的简单!  
  select   x.account,x.seqdate,min(balance)   from  
  (select   *   from   (select   distinct   account   from   test_sql)   a,   test_date   b   )   x,test_sql   y  
  where   x.account   =   y.account   and   x.seqdate   >=   y.paydate  
  group   by   x.account,x.seqdate  
  Top

151 楼xinpingf(白开心)回复于 2001-11-23 21:48:31 得分 0

其实这个问题很简单就搞定了,做一个视图不就行了?  
   
  table1   :  
      yh           rq                       cash  
        1           1-jan-2001         100  
        2           1-jan-2001         100  
        ...             ...                 ...  
      100         1-jan-2001         100  
  每天支出后,插入一条cash为负的记录  
   
  create   or   replace   view   v_drye   as         --当日余额  
        select   yh,   sum(cash)   drye    
            from   table1    
          group   by   yh   ;  
   
  create   or   replace   view   v_mrye   as         --每日余额  
        select   distinct   yh,   rq   ,   (select   sum(cash)    
                                                              from   table1  
                                                            where   yh   =   a.yh    
                                                                and   rq   <   a.rq   )   mrye    
          from   table1   a   ;  
   
   
  不过,如果数据量大的话,该视图会很慢的  
  Top

152 楼qulin(大头)回复于 2001-11-23 21:58:52 得分 0

表结构:  
  表名:rec  
  结构:  
      user   账号   int   (1-100)  
      time   日期   int   (1-100)  
      cash   余额   int   (1-100)  
  表中先插好第一天的所有账号的余额100,即表中先有100条记录。  
   
  以下语句的基本思想是:  
      用账号连接日期把空缺的日期补上。  
   
  select   a.user   as   账号,  
  b.user   as   日期,  
  min(rec.cash)   as   余额    
  from   (select   distinct   user   from   rec)   a   cross   join  
  (select   distinct   user   from   rec)   b   left   outer   join   rec   on    
    a.user   =   rec.user    
  where   rec.time   <   b.user  
  group   by   a.user,b.user  
  order   by   b.user,a.user  
  Top

153 楼qulin(大头)回复于 2001-11-23 22:03:51 得分 0

修改一点点  
  where   rec.time   <=   b.user  
                                ~~~Top

154 楼hellowbh(OneBowie)回复于 2001-11-24 14:24:09 得分 0

关注。Top

155 楼wylyf(李寻欢)回复于 2001-11-24 17:02:07 得分 0

表的结构是;   (data)                                                   另外用一个表存结果信息:(bf)  
  用户号:USERID     int                                                   用户号:USERID   int  
  时间:DAT               smalldatetime                               时间:DAT             smalldatetime  
  余额:NUM               int                                                   余额:NUM             int  
  declare   @i,@tmpint   int  
  declare   @maxdat,@bufdat   smalldatetime  
  select   @bufdat='01-11-01'  
  select   @maxdat=dateadd(dd,100,@bufdat)  
  while   @bufdat<@maxdat  
        begin  
      select   @i=1  
            while   @i<100    
              begin  
          /*insert   into   bf   select   top   1   *   from   dat   where   USERID=@i   and   dat<=@bufdat   order   by   num   在我机器上没这样用,不知道行不行*/  
          declare   cur   cursor   for  
  select   top   1   num   from   dat   where   userid=@i   and   dat<=@bufdat   order   by   num  
  open   cur  
  fetch   next   from   cur   into   @tmpint  
          select   @i=@i+1                                          
  deallocate   cur  
  end  
  select   @bufdat=dateadd(dd,1,@bufdat)  
  endTop

156 楼wylyf(李寻欢)回复于 2001-11-24 17:06:34 得分 0

在select   @i=@i+1前面应该加上:  
  insert   into   bf   values   (@i,@bufdat,@bufint)Top

157 楼fulcrum_yk(读在死后)回复于 2001-11-24 21:53:18 得分 0

CREATE   PROCEDURE   xx   @Curdate   datetime   AS  
  DECLARE  
  @COUNTER   NUMERIC  
  SELECT   @COUNTER   =   1  
  while   (@COUNTER<=30)  
  begin    
  select   min(parent_price)   parent_price   ,@curdate   parent_data,parent_name   from   parent   where   parent_data<=@curdate   group   by   parent_name  
  select   @curdate=dateadd(day,1,@curdate)  
  select   @COUNTER=@COUNTER+1  
  end  
   
   
   
   
   
  Top

158 楼fulcrum_yk(读在死后)回复于 2001-11-24 21:55:50 得分 0

CREATE   PROCEDURE   xx   @Curdate   datetime   AS  
  DECLARE  
  @COUNTER   NUMERIC  
  SELECT   @COUNTER   =   1  
  while   (@COUNTER<=100)  
  begin    
  select   min(parent_price)   parent_price   ,@curdate   parent_data,parent_name   from   parent   where   parent_data<=@curdate   group   by   parent_name  
  select   @curdate=dateadd(day,1,@curdate)  
  select   @COUNTER=@COUNTER+1  
  end  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
  Top

159 楼jilongge(果子)回复于 2001-11-26 11:10:54 得分 0

真是太好了,众人拾材火焰高啊Top

160 楼jilongge(果子)回复于 2001-11-26 15:25:09 得分 0

人气大集啊!!Top

161 楼greenxiar(瓜瓜)回复于 2001-11-26 21:46:20 得分 0

其实设计很标准的  
  第一个表记录每个用户的余额状态——用户余额表  
  第二个表记录用户存取的流水事务——用户存取流水表  
  如果疯狂一点的设计方法,针对你的应用可以设计第三个表——时段余额表  
  初始时把第一个表的全部记录拷过来,每次第二个表存取事务发生时这个表添一条记录——当时的用户余额。  
   
  只有前两个表的设计非常标准,针对你的应用时出结果是需要些技巧的  
  加上的第三个表实际上是对你的应用的预处理,查询当时的性能很高Top

162 楼jilongge(果子)回复于 2001-11-27 13:57:36 得分 0

好帖子大家好好看看Top

163 楼MARSHALYIN(幽客)回复于 2001-11-27 15:40:41 得分 0

Very   nice!  
  jilongge(果子):不错,这种场面难得一见呐!!Top

164 楼jilongge(果子)回复于 2001-11-28 12:26:02 得分 0

大家对这个帖子不敢兴趣了?Top

165 楼nononono(null,null)回复于 2001-11-28 12:32:44 得分 0

每个答案都得不到评价,   这个贴子已经没有意义了.Top

166 楼jilongge(果子)回复于 2002-01-09 16:47:31 得分 0

哈哈!upTop

167 楼icevi(按钮工厂)回复于 2002-01-09 17:02:58 得分 0

怎么又拱上来了,好烦哪!  
  *_*Top

168 楼sky_blue(蓝天2007)回复于 2002-01-09 17:08:30 得分 0

呵呵,   我收Top

169 楼xinpingf(白开心)回复于 2002-01-09 17:49:12 得分 0

赶紧下去Top

相关问题

  • 微软面试题!
  • 微软面试题
  • 一道微软面试题
  • 微软面试题之二
  • 微软面试题目(一)
  • 微软面试题目(二)
  • 微软面试题目(三)
  • 微软的面试题目?
  • 微软面试考题
  • 微软的一道面试题!!!!!

关键词

  • 账户
  • 帐号
  • 存储过程
  • 账号
  • 余额
  • seqdate
  • account
  • yh
  • 记录
  • facctid

得分解答快速导航

  • 帖主:jilongge
  • microyzy
  • leorb

相关链接

  • SQL Server类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问