原文見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)的網站?