锁定老帖子 主题:SQL 小技巧
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-08-21
第三个问题,先写出代码来吧。等有点时间再解释一下。第四个问题其实可以照猫画虎的:
select x.ticker, x.star, x.percent from perf x left join perf nothing on x.ticker = nothing.ticker and (x.percent < nothing.percent or (x.percent=nothing.percent and x.star < nothing.star or x.star=nothing.star and x.date < nothing.date) ) where nothing.ticker is null |
|
返回顶楼 | |
发表时间:2008-08-21
嗯。稍微解释一下第三个问题的query。
其实它和第四个问题都可以归结为一类“根据某个自定义全序来寻找最优记录“。这个全序(java里的comparator),在第三题里面被定义为: r1 > r2 iff r1.(percent, star, date) > r2.(percent, star, date) 如果sql支持矢量比较的话,query本来可以简单到: select x.* from perf x left join perf nothing on x.ticker = nothing.ticker and x.(percent, star, date) < nothing.(percent, star, date) where nothing.ticker is null 可以这么读:对每一个ticker, 找到(percent, star, date)这个矢量值最大(也就是说没有比它更大)的那个记录。 只不过因为缺乏内建矢量比较,被迫只好人肉用and/or来表达矢量比较。 那么第四个问题呢,用同样的(没有比它更好<=>最好)方式,可以写成: select x.id from perf x left join perf nothing on x.(ticker, date) = nothing.(ticker, date) and x.(star, id) < nothing.(star, id) where nothing.id is null 读出来就是:对每个ticker+date,找到(star, id)这个矢量值最大(没有比它更大)的那个记录的id。 |
|
返回顶楼 | |
发表时间:2008-08-21
非常不错,受教了!
|
|
返回顶楼 | |
发表时间:2008-08-21
引用 on x.ticker = nothing.ticker and
where nothing.ticker is null 矛盾!? |
|
返回顶楼 | |
发表时间:2008-08-21
lz是强人。向lz学习。
手头只有sybase. 而Sybase不支持在outter join的时候再做其他连接, 头痛. 在这种情况下lz有什么好建议么? |
|
返回顶楼 | |
发表时间:2008-08-21
原来是高中数学的“n^x*n^y=n^(x+y)”呀,无脸见高中数学老师。
|
|
返回顶楼 | |
发表时间:2008-08-21
nihongye 写道 引用 on x.ticker = nothing.ticker and
where nothing.ticker is null 矛盾!? left join self nothing on ... where nothing.id is null 这个where nothing.id is null就是定义nothing的。所谓的nothing,就是说"id is null"或者说”不存在这样的记录“。 left join的时候,把所有右面不存在的记录填成null,而我们要找的就是这些不存在比它大的记录。 |
|
返回顶楼 | |
发表时间:2008-08-21
ajoo 写道 珍爱生命,远离存储过程! 请问楼主,此话怎讲? |
|
返回顶楼 | |
发表时间:2008-08-21
moses3017 写道 ajoo 写道 珍爱生命,远离存储过程! 请问楼主,此话怎讲? 存储过程背弃了sql的声明式编程的理念,重新倒退回了过程式代码。 它一般来说不好维护,很容易产生代码重复,不容易重构,不容易测试,数据库提供的语言功能也限制了表达能力(你能oo么?能抽象么?能fp么?)。我曾经维护过数千行的存储过程代码,到处copy-paste。要改点东西真是头疼呀。其实它做的事情如果sql写好一点,本来三四百行sql就可以搞定的。 它允许你做循环,支持游标,就客观上培养了很多懒人不去好好写sql,不去仔细研究query plan,而是用笨拙的循环写出乌龟爬一样的系统,然后埋怨数据库,或者埋怨存储过程。 而且很多情况下用宝贵的数据库服务器的处理器资源去做本来不该数据库做的事情,是可耻的浪费。 |
|
返回顶楼 | |
发表时间:2008-08-22
ajoo 写道 nihongye 写道 引用 on x.ticker = nothing.ticker and
where nothing.ticker is null 矛盾!? left join self nothing on ... where nothing.id is null 这个where nothing.id is null就是定义nothing的。所谓的nothing,就是说"id is null"或者说”不存在这样的记录“。 left join的时候,把所有右面不存在的记录填成null,而我们要找的就是这些不存在比它大的记录。 明白,谢谢了。习惯把条件写在where里,你的思路比较别致。 |
|
返回顶楼 | |