今天在ITPUB拜讀了梁敬彬老師的一段內容,講標量子查詢需要注意的地方,聯想其在日常工作中隨處可見,但個人從來沒有思考過這樣的問題,深感汗顏。
特此摘錄下來。
原文出處:http://www.itpub.net/thread-1338364-1-1.html
STEP1 構造測試表和數據
CREATE TABLE TEST111 (ID INT ); INSERT INTO TEST111 VALUES (1); INSERT INTO TEST111 VALUES (2); INSERT INTO TEST111 VALUES (3); COMMIT; DROP TABLE TEST222; CREATE TABLE TEST222 (ID INT ); INSERT INTO TEST222 VALUES (1); INSERT INTO TEST222 VALUES (2); INSERT INTO TEST222 VALUES (NULL); COMMIT;
STEP2
--標量子查詢 SELECT T1.ID,(SELECT T2.ID AS T2ID FROM TEST222 T2 WHERE T2.ID = T1.ID) FROM TEST111 T1;
--左連接 等同於標量子查詢 SELECT T1.ID,T2.ID FROM TEST111 T1,TEST222 T2 WHERE T1.ID = T2.ID(+); --等值查詢 SELECT T1.ID,T2.ID FROM TEST111 T1,TEST222 T2 WHERE T1.ID = T2.ID;
有經驗的開發不員不難看出二者的區別。
下面大家思考一下下面的語句是等價的嗎,若果不是,要怎么改寫呢
select a.username, count(*) from all_users a, all_objects b where a.username = b.owner (+) group by a.username order by a.username;
select a.username, (select count(*) from all_objects b where b.owner = a.username) cnt from all_users a
group by a.username order by a.username;
大家不妨試着執行看下結果,可以看到是有差異的。那么該如何改呢,
select a.username, count(owner) from all_users a, all_objects b where a.username = b.owner (+) group by a.username order by a.username;
因為count(*) 在b表無記錄匹配的情況下,也會返回1。
count(*)與count(1)包含null列統計,count(id),統計id不為null的列和。
總結:項目中如果遇到需要寫標量子查詢的地方,不妨先按上面的內容思考下,是否會出現包含不想要的結果。