有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数据库管理员),他说他做不了,给我写了个存储过程,因为他用到了游标,我也没看明白。昨天弄了一上午终于弄出来了,其实很简单的:
2 (( SELECT TOP 1 endstar
3 FROM updatelog
4 WHERE memberinfo.memberid = updatelog.memberid
5 ORDER BY updatetime DESC ) IS NULL ) THEN memberinfo.star ELSE
6 ( SELECT TOP 1 endstar
7 FROM updatelog
8 WHERE memberinfo.memberid = updatelog.memberid
9 ORDER BY updatetime DESC ) END AS 星级
10 FROM 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这个函数
2 (( SELECT MAX (endstar)
3 FROM updatelog
4 WHERE memberinfo.memberid = updatelog.memberid), star) AS 星级
5 FROM memberinfo