posts - 21,  comments - 60,  trackbacks - 3

有memberinfo和updatelog两个表,通过memberinfo的memberid和updatelog的memberid对两个表进行关联,memberinfo纪录会员基本信息,updatelog纪录会员的升级信息。
memberinfo数据如下
memberid   star
001           1
002           1
003           2

updatelog数据如下
memberid  endstar   updatetime
001           2           2005-5-24
001           3           2005-5-28
001           5           2005-6-9
002           4           2005-5-29

想得到的数据为
会员号   星级
001          5
002          4
003          2

最初我是通过C#读取两个表的数据,然后一一对应组成一个新表,这样执行效率是非常低的,而且代码还非常多。就想通过SQL语句查询得到,在csdn上发帖子也没人解答。问一个师兄(他毕业后一直是Oracle数据库管理员),他说他做不了,给我写了个存储过程,因为他用到了游标,我也没看明白。昨天弄了一上午终于弄出来了,其实很简单的:

 1SELECT memberid AS 会员号, CASE WHEN
 2          ((SELECT TOP 1 endstar
 3          FROM updatelog
 4          WHERE memberinfo.memberid = updatelog.memberid
 5          ORDER BY updatetime DESCIS NULLTHEN memberinfo.star ELSE
 6          (SELECT TOP 1 endstar
 7         FROM updatelog
 8         WHERE memberinfo.memberid = updatelog.memberid
 9         ORDER BY updatetime DESCEND AS 星级
10FROM dbo.memberinfo

不过(SELECT TOP 1 endstar FROM updatelog WHERE memberinfo.memberid = updatelog.memberid  ORDER BY updatetime DESC)这一句执行两次,肯定会消耗资源的,不知道有没有更好的解决方法。

最近的体会就是我写的程序很少能体现的出数据库管理系统的性能(都是用程序读取数据出来然后再自己去组合数据),所以我从不敢说Oracle和SQL Server到底哪个好。这个东西用SQL写出来后,代码比以前少很多,可读性也更强了。数据库程序员还是好好学学怎么写SQL语句吧,这个能提升做的系统的性能。


2006-4-3
今天看到Ember 给我的留言,然后就又看到这篇博客,这里会造成SQL语句那么长,其实是数据库设计不好的原因,如果数据库设计合理,完全不会造成查询的困难。
另外看到这个SQL语句,想到了可以简化的方法,就是使用ISNULL这个函数

1SELECT memberid AS 会员号, ISNULL
2          ((SELECT MAX(endstar)
3          FROM updatelog
4          WHERE memberinfo.memberid = updatelog.memberid), star) AS 星级
5FROM memberinfo

 

posted on 2005-11-01 12:56 山伟 阅读(...) 评论(...) 编辑 收藏