select * 排除字段_编写 SQL 的排除联接
有兩個表,就叫作源表和目標(biāo)表吧。它們有一個相同的字段,通過該字段可以把源表和目標(biāo)表關(guān)聯(lián)在一起,我們希望從源表中檢索到的記錄里的關(guān)聯(lián)字段的值沒有存在目標(biāo)表中。舉個例子,源表 dept,目標(biāo)表 emp,獲取 dept 表中部門編號不在 emp 表中的記錄。檢查兩張表的數(shù)據(jù),我們發(fā)現(xiàn) emp 表中沒有部門編號 40 的數(shù)據(jù)。
圖1 emp 表的數(shù)據(jù)圖2 dept 表的數(shù)據(jù)實現(xiàn)這種的查詢的方法有很多,不同的實現(xiàn)方式的性能也會不一樣。我們就來看看都有哪些方法?
NOT IN
SELECT * FROMdept WHERE deptno NOT IN (SELECT deptno FROMemp)這種實現(xiàn)方式需要注意一個點,就是在 not in 里面不能出現(xiàn) NULL,如果出現(xiàn) NULL 就會查不到結(jié)果。比如下面這條 SQL,沒有數(shù)據(jù)返回。
SELECT dname FROMdept WHERE deptno NOT IN (SELECT deptno FROMemp UNION ALL SELECT NULL)為什么是這樣呢?
因為在邏輯運算中,涉及到 NULL 的操作的結(jié)果仍為 NULL。not in 可以改寫成 or 的形式,比如 deptno not in(10,NULL) 展開成 or 的表達(dá)式是:not (deptno = 10 or deptno = NULL),最終的表達(dá)式是 not NULL 。
NOT EXISTS
使用 not exists 可以避免由于目標(biāo)表的關(guān)聯(lián)列上出現(xiàn) NULL 而查不出數(shù)據(jù)。
WITH e AS (SELECT deptno FROMemp UNION ALL SELECT NULL) SELECT * FROMdept WHERE NOT EXISTS (SELECT NULL FROMe WHERE e.deptno = dept.deptno)使用 not exists 的 SQL 的一般形式:
SELECT 選擇列 FROM源表 WHERE NOT EXISTS (SELECT NULL FROM目標(biāo)表 WHERE 關(guān)聯(lián)字段)在 MySQL 5.6 之前,子查詢的性能表現(xiàn)得比較差,因而就有人想著把子查詢改成連接的方式以提高查詢性能。
LEFT JOIN
通常,我們會想到使用 NOT IN、NOT EXISTS 做排除操作。其實,使用 LEFT JOIN 也可以達(dá)到相同的目的。
SELECT d.* FROMdept d LEFT JOIN emp e ON e.deptno = d.deptno WHERE e.deptno IS NULL對于表達(dá)式 a left join b ,不管 b 表中是否有數(shù)據(jù)可以和 a 表匹配得上,a 表總是能返回所有數(shù)據(jù)。如果 b 表中沒有數(shù)據(jù)能匹配得上 a 表,在查詢結(jié)果中會使用 NULL 填充 b 表的列。因此,通過過濾條件 b.關(guān)聯(lián)列 is NULL 可以找到只存在于 a 表中的數(shù)據(jù)。
總結(jié)
來源:SQL實現(xiàn)
作者:zero
原文:編寫 SQL 的排除聯(lián)接
總結(jié)
以上是生活随笔為你收集整理的select * 排除字段_编写 SQL 的排除联接的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python一元加号_Python一元方
- 下一篇: linux cmake编译源码,linu