JOIN
from vs join
參考資料:(https://stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause)
In vs Exist vs Join 效能比較 (SQL Server)
參考資料:(https://tw.saowen.com/a/dfa016357c6a6c973d5cb9fc90a4e35ec95bba36c8f2d8ab2d2627f6ffe6f115)
[SQL]Join的觀念
參考資料:(https://dotblogs.com.tw/hatelove/2010/01/23/sql-join-concept)
IN vs EXISTS vs JOIN (Oracle)
參考資料:(https://explainextended.com/2009/09/30/in-vs-join-vs-exists-oracle/)
語法轉換範例:
IN
EXIST
JOIN/DISTINCT
結論: (2009/09/30)
IN看似效率很差,其實Oracle 有對IN做很好的優化,不管被查詢的欄位是否有被建立索引,都很好。
EXISTS與IN的優化完全相同,但是IN更具有可讀性和簡潔性。
JOIN
參考資料:(https://dotblogs.com.tw/hatelove/2010/01/23/sql-join-concept) 參考資料:(https://blog.wu-boy.com/2009/01/mysqlleft-right-inner-outer-join-%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/)
四種JOIN
join = inner join
left join = left outer join
right join = right outer join
full join
範例圖
下面整個搜尋結果 -- full join
倒數第二筆去掉 -- left join
倒數兩筆都去掉 -- inner join
最後一筆去掉 -- right join
full join 也等於
left join union right join
(+) ((不推薦使用
參考資料:(https://matthung0807.blogspot.com/2017/09/oracle-outer-join-operator.html)
Oracle PL/SQL的(+)
符號代表OUTER JOIN
的意思。 不過Oracle官方直接建議還是直接使用OUTER JOIN
語法,不建議使用舊的(+)
語法。 此外在Java程式JDBC使用舊的(+)
語法會導致ResultSet
部分欄位的值為空,所以還是不要使用吧。
(+)有使用上的限制,詳細請去看操考資料。
Natural Join
同 inner join,差別是不用寫on 會根據相同欄位自動連接
Cross join
參考資料: CROSS JOIN 關鍵字 (SQL CROSS JOIN Keyword) - 交叉連接(https://www.fooish.com/sql/cross-join.html)
交叉連接為兩個資料表間的笛卡兒乘積 (Cartesian product),兩個資料表在結合時,不指定任何條件,即將兩個資料表中所有的可能排列組合出來,以下例而言 CROSS JOIN 出來的結果資料列數為 3×5=15 筆,因此,當有 WHERE、ON、USING 條件時不建議使用。
參考資料: Oracle 的 CROSS JOIN 文件(https://docs.oracle.com/javadb/10.6.2.1/ref/rrefsqljcrossjoin.html#rrefsqljcrossjoin)
產生兩個表的笛卡爾乘積,和其他JOIN不同,不允許指定on語句。但可以在SELECT中指定WHERE語句。
相同
相同
相同
連接:內連接、外連接、反連接、半連接
內連接其實就是上面的 inner join
外連接也就是上面的 outer join
那麼反連接 和半連接 又是什麼呢?
半連接與反連接
參考資料:(http://blog.sina.com.cn/s/blog_7c5a82970101ix2l.html) 參考資料:半連接(https://riptutorial.com/zh-TW/oracle/example/14685/%E5%8D%8A%E9%80%A3%E6%8E%A5) 參考資料:反連接(https://riptutorial.com/zh-TW/oracle/example/14684/%E5%8F%8D%E9%80%A3%E6%8E%A5)
是針對IN, EXISTS, NOT IN, NOT EXISTS 的變形,前兩者為半連接,後兩者為反連接。
子查詢在FROM裡面,叫做 IN-LINE VIEW,在WHERE子句中叫做NESTED SUBQUERY(嵌套子查詢)。 IN, EXISTS, NOT IN, NOT EXISTS 都屬於嵌套子查詢。
IN, EXISTS 展開變成 SEMI-JOIN。 NOT IN, NOT EXISTS 是轉換成 ANTI-JOIN。
半連接的重點在於:對於外表的某筆記錄,在內表找到一個匹配的紀錄就返回外表)
從Oracle 9i開始,IN 和EXISTS 已經沒有區別,執行計畫是一樣的。
NOT EXISTS 與 NOT IN 的區別在於處理NULL
NOT IN 查看子結果中有沒有NULL,若有,return false。 NOT EXISTS 不關心NULL,只關心紀錄數,如果有紀錄,返回false。
NOT IN可能在匹配列上,引起效能問題,原因是索引失敗
IN 和EXISTS
IN
參考資料:(https://www.techonthenet.com/oracle/in.php)
寫法 expression IN (value1, value2, ... valueN)
用來
判斷某個欄位的值,有沒有在某個陣列中。
有個說法是IN 後面接的陣列,裡面的value數量不能超過1000,實際去google "oracle IN 限制" 也可以查到相關的討論,不過根據下面的連結
因為以前SQL的長度不能超過32K,因為輸入參數只能是VARCHAR2,但是 11G 以後,可以用 CLOB 作為數入參數,所以取消了這個限制。
所以倘若Oracle版本在11G以前的,的確是有1000個的限制,但11G之後的可能有待嘗試。
EXISTS
參考資料:(https://www.techonthenet.com/oracle/exists.php)
寫法 where EXISTS ( subquery );
用來
判斷某個子查詢有沒有返回值,倘若有一個就終止,return true。倘若無,return false。
拿來兩個表查詢
效能比較
有索引的欄位
沒有索引的欄位
set操作符(UNION, UNION ALL, INTERSECT, MINUS)
參考資料:(https://blog.csdn.net/jssg_tzw/article/details/53509464)
Oracle Database 的集合操作屬於SELECT 的高級用法,用數學的觀念來看,就是聯集、交集、差集。
UNION 聯集(去除重複) A + B - (A和B重複部分)
UNION ALL 聯集(保留重複) A + B
INTERSECT 交集 A和B重複部分
MINUS 差集 (上方比下方多出來的部分) A - B *MINUS 是 Oracle的,MS SQL 是用 except
Last updated