原文见http://www.itpub.net/showthread.php?s=&threadid=654
oldwain
欣赏一个奇妙的sql(也来点正经的, 不能让他们说我们只会瞎灌水).
以下语句用来随机查找三条记录
select * from emp
where empno in ( select empno
from (select empno
from emp
order by dbms_random.random )
where rownum <= 3 )
/
不要怀疑这个语句有什么错误, 在oracle815以上肯定没有问题.
问题是:
1. dbms_random.random 产生的是一个8位或10位(随版本不同而不同),
order by 一个如此大的数字什么含义?
2. order by 不允许使用比实际列数更大的列(通过执行select * from emp order by 20的错误信息可以知道)
那么, 这个语句究竟为什么能够执行, 怎么执行的?
qiaoyu
我的oracle8.1.6上就不能执行!
oldwain
不能执行? 是不是没有安装dbms_random package? 安装后应该没有问题的.
执行ORACLE_HOME/RDBMS/ADMIN/CATOCTK.SQL, 安装dbms_random package
如果是8.1.5, 还需要在执行上面的语句之前, 执行:
execute dbms_random.initialize(1000); -- 其中1000为一个生成随机数的种子, 取任何值都可以.
windff
很好玩的SQL,dbms_random.random生成的一系列数字,不是什么列号,是作为一列来看待,如果SQL写成这样就容易理解了
select * from emp where empno in (select empno from (select empno,dbms_random.random a oder by a ) where rownum<3)
oder by 后面是可以跟一个常量的,这个常量被当作一个列来看待,
例如: select * from emp order by to_number('10')
是这样吗?
oldwain
有道理!
我原来钻牛角尖了, 总以为 order by 后面的数字一定是列号.
谢谢windff的解释, 这个问题让我绕了好长时间了.
windff
这个问题很好玩,这样的SQL不是很容易能见到的,也要感谢你了
oldwain
记得是92,93年前后, 看过一本有关occc(Obfuscated C Code Contest, 原版的)的书, 很有趣,
不知到有没有Obfuscated SQL Code Contest ?
以下是第一届occc的一段代码(相对后期的来说, 算很简单了), 对c有兴趣的, 不妨解释一番:
代码:--------------------------------------------------------------------------------
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hello, world!/n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
--------------------------------------------------------------------------------
下面的程序, 可以成为世上兼容性最好的程序, 它兼容c, fortran77, bourne shell !!!!!!!
代码:--------------------------------------------------------------------------------
cat =13 /*/ >/dev/null 2>&1; echo "Hello, world!"; exit
*
* This program works under cc, f77, and /bin/sh.
*
*/; main() {
write(
cat-~-cat
/*,'(
*/
,"Hello, world!"
,
cat); putchar(~-~-~-cat); } /*
,)')
end
*/
--------------------------------------------------------------------------------
windff
oldwin得好东西真多,看了上面的程序头都大,原来一直以为自己对c还算是知道的不少得,现在再看,简直什么都不知道,看杨振要好好学习了
oldwain
呵呵, 这与个人的水平无关.
要是很容易看懂, 就不能称为"Obfuscated "了.
下面是Obfuscated c 的入门程序片断, 要求在最快的时间(比如说10秒之内)内说出它的功能:
代码:--------------------------------------------------------------------------------
{ a = a + b;
b = a - b;
a = a -b;}
--------------------------------------------------------------------------------
windff
真是让人糊涂的代码
其实就是吧a和b得值对调了一下,
真是佩服,为了少定义一个变量,竟然用到这样的办法,佩服啊
这书什么地方有,真想找来看看
young107
有趣的SQL,复杂的C语句,绕得我头都晕了。不过最后一段的功能好像是将A赋值为0。
oldwain
windff说得对, 这个方法确实比使用一个临时变量的效率要高!!!
想看更多的occc, 可以到http://www.ioccc.org/
有兴趣的话, 还可以去参加比赛(奖金情况我可不了解)
windff
谢谢oldwain,这样的问题有趣,能体验到乐趣,不象现在给客户开发的时候大多数时候是搬砖,一点乐趣都没有
feng_xin
不明白
select * from emp
where empno in ( select empno
from (select empno
from emp
order by dbms_random.random )
where rownum <= 3 )
1. dbms_random.random 返回一个随机数,那么order by dbms_random.random 应该相当于 order by '20'?
2. 若 select empno from emp order by '20' 的话,order by 启不是不起作用?
3.那么此SQL启不是永远返回前三条记录?
是不是这应该样写
select * from emp
where empno in ( select empno
from (select empno,dbms_random.random aa
from emp
order by aa)
where rownum <= 3 )
oldwain
两个语句应该是等价的.
注意:
1. 如果select empno from emp order by 20, 会出错(20 不是一个有效的列号),
但select empno from emp order by '20' 没有问题 (把'20'当作一个常量计算列)
2. order by dbms_random.random 应该相当于 order by '20' ?
不!
dbms_random.random 并不是只计算一次, 而是针对每一行计算一个, 所以得到的是一个变动的计算列, 而不是常量计算列.
做一下试验, 能够好的理解这之间的差异.
internal
这段C程序有味道啊,想起大学时好多同学都津津乐道于此的。
程序原来也可以编得像首诗呵。
你站在桥上看风景,
看风景的人在楼上看你。
明月装饰了你的窗子,
你装饰了别人的梦。
——卞之琳
parrotao
Add this topic to our E-magazine ?
It is very very very very funny, very very very exciting !!!
Thanks All
oldwain
呵呵, 把这篇帖子又给翻出来了?
我也很希望能做一些类似的小趣文放到e-mag里面.
可惜, 没有找到这方面的资源.
有没有人能提供一些有趣味sql(类似我上面提到的occc)的站点?