论坛首页 综合技术论坛

SQL 小技巧

浏览 35181 次
锁定老帖子 主题:SQL 小技巧
该帖已经被评为精华帖
作者 正文
   发表时间:2008-08-22  
ajoo 写道
第一个问题
...
我的解决方法嘛,只读提过了。为了完整,我再贴一遍我的用自然对数的方法:
select ticker, (exp(sum(log(1 + percent/100))) - 1) / 100 as accumulated_percent
from perf where date between startdate and enddate group by ticker

...


很不错的SQL 收藏了 

不过第一题有个小问题 计算增长率的部分应该是:
(exp(sum(log(1 + percent/100))) - 1) * 100

select ticker, (exp(sum(log(1 + percent/100))) - 1) * 100 as accumulated_percent
from perf where date between startdate and enddate group by ticker
0 请登录后投票
   发表时间:2008-08-22  
ajoo 写道
第三个问题,先写出代码来吧。等有点时间再解释一下。第四个问题其实可以照猫画虎的:
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


在使用外链接的时候,where clause 跟left join on clause,数据库优化器会先使用哪个clause过滤数据啊?
0 请登录后投票
   发表时间:2008-08-22  
icefishc 写道
lz是强人。向lz学习。
手头只有sybase. 而Sybase不支持在outter join的时候再做其他连接, 头痛.  在这种情况下lz有什么好建议么?

我也用sybase,这种写法是SQL的标准,不会有问题的。
0 请登录后投票
   发表时间:2008-08-22  
shoulders 写道
ajoo 写道
第三个问题,先写出代码来吧。等有点时间再解释一下。第四个问题其实可以照猫画虎的:
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


在使用外链接的时候,where clause 跟left join on clause,数据库优化器会先使用哪个clause过滤数据啊?

这是根据索引来的,不是简单的谁先谁后。

咱们先假设ticker上有索引。

那么比如你的where clause如果有"and ticker in ('a','b','c')",这个肯定就先index seek了。在seek出来的基础上,在怎么搞都无所谓了。

但是where nothing.ticker is null肯定不会是先被过滤的,因为做不到,只有join之后你才知道哪个ticker是null。

所以据我的经验,如果没有上面那种额外的过滤条件的话,根据数据量的大小,这里可能是一个merge join或者hash join配上table scan/index scan。
0 请登录后投票
   发表时间:2008-08-22  
对于oracle

第一个问题
可以用自定义集约函数搞定

可以参看
http://www.iteye.com/post/519866
那里有一个关于字符串连接(concat)用的自定义集约函数

第二个问题,

select 
      基金表.PK
    , count(decode(基金表.分数, 5, 1, 0)) as count_5
    , count(decode(基金表.分数, 4, 1, 0)) as count_4
    , count(decode(基金表.分数, 3, 1, 0)) as count_3
    , count(decode(基金表.分数, 5, 1, 4, 1, 3, 1, 0)) as count_543
from 基金表
group by 基金表.PK
having count_543 > 2
0 请登录后投票
   发表时间:2008-08-26  
sql调优还是蛮好玩的
0 请登录后投票
   发表时间:2008-09-05  
很支持,我喜欢,我也喜欢搞这种事情。
0 请登录后投票
   发表时间:2008-09-08  
shoulders 写道
icefishc 写道
lz是强人。向lz学习。
手头只有sybase. 而Sybase不支持在outter join的时候再做其他连接, 头痛.  在这种情况下lz有什么好建议么?

我也用sybase,这种写法是SQL的标准,不会有问题的。



http://manuals.sybase.com/onlinebooks/group-as/asg1250e/sqlug/@Generic__BookTextView/12062;hf=0
  真的不行的
0 请登录后投票
   发表时间:2008-09-09  
armorking 写道
对于oracle
第二个问题,

select 
      基金表.PK
    , count(decode(基金表.分数, 5, 1, 0)) as count_5
    , count(decode(基金表.分数, 4, 1, 0)) as count_4
    , count(decode(基金表.分数, 3, 1, 0)) as count_3
    , count(decode(基金表.分数, 5, 1, 4, 1, 3, 1, 0)) as count_543
from 基金表
group by 基金表.PK
having count_543 > 2

这里的having count_543 > 2可以这么写吗?
没听说查询出来的别名可以作having过滤项。至少Oracle9i下这是不行的。
0 请登录后投票
   发表时间:2008-09-09  

第三个问题,可以使用数据库提供的分析函数呀

select ticker, percent, star, ymonth  
from (  
  select ticker, percent, star, ymonth,  
    row_number () over (partition by ticker order by percent desc, star desc, ymonth desc) as rrow  
   from performance  
  )  
where rrow=1;  

 

我想ajoo说的是不使用分析函数的情况下解决问题的办法吧。

0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics