SQL集合運算

2021-10-12 16:37:35 字數 3430 閱讀 9120

1.表的加減法

(1)定義

集合在數學領域表示「各種各樣的事物的總和」,在資料庫領域表示記錄的集合.。具體來說,表、檢視和查詢的執行結果都是記錄的集合,其中的元素為表或者查詢結果中的每一行。

在標準 sql 中,分別對檢索結果使用unionintersectexcept來將檢索結果進行並,交和差運算,像unionintersectexcept這種用來進行集合運算的運算子稱為集合運算子。

(2)union

union 等集合運算子通常都會除去重複的記錄,

(3)or

使用 union 對兩個查詢結果取並集, 和在乙個查詢中使用 where 子句, 然後使用 or 謂詞連線兩個查詢條件, 能夠得到相同的結果。

(4)包含重複行的集合運算 union all

union 會對兩個查詢的結果集進行合併和去重, 這種去重不僅會去掉兩個結果集相互重複的, 還會去掉乙個結果集中的重複行。在 union 的結果中保留重複行的語:在 union 後面新增 all 關鍵字。

2.鏈結 (join)

union和intersect 等集合運算的特徵就是以行方向為單位進行操作. 通俗地說, 就是進行這些集合運算時, 會導致記錄行數的增減. 使用 union 會增加記錄行數,而使用 intersect 或者 except 會減少記錄行數.

但這些運算不能改變列的變化, 雖然使用函式或者 case表示式等列運算, 可以增加列的數量, 但仍然只能從一張表中提供的基礎資訊列中獲得一些"引申列", 本質上並不能提供更多的資訊. 如果想要從多個表獲取資訊, 例如, 如果我們想要找出某個商店裡的衣服類商品的名稱,數量及**等資訊, 則必須分別從 shopproduct 表和 product 表獲取資訊。

鏈結(join)就是使用某種關聯條件(一般是使用相等判斷謂詞"="), 將其他表中的列新增過來, 進行「新增列」的集合運算. 可以說,鏈結是 sql 查詢的核心操作, 掌握了鏈結, 能夠從兩張甚至多張表中獲取列, 能夠將過去使用關聯子查詢等過於複雜的查詢簡化為更加易讀的形式, 以及進行一些更加複雜的查詢.

(1)內鏈結 inner join

要點一: 進行鏈結時需要在 from 子句中使用多張表.

之前的 from 子句中只有一張表, 使用關鍵字 inner join 就可以將兩張表鏈結在一起了。

要點二:必須使用 on 子句來指定鏈結條件.

在進行內鏈結時 on 子句是必不可少的(大家可以試試去掉上述查詢的 on 子句後會有什麼結果).

on 子句是專門用來指定鏈結條件的, 我們在上述查詢的 on 之後指定兩張表鏈結所使用的列以及比較條件, 基本上, 它能起到與 where 相同的篩選作用。

要點三: select 子句中的列最好按照 表名.列名 的格式來使用.

當兩張表的列除了用於關聯的列之外, 沒有名稱相同的列的時候, 也可以不寫表名, 但有表名更直觀。 

但是, 如果兩張表有其他名稱相同的列, 則必須使用上述格式來選擇列名, 否則查詢語句會報錯.

(2)結合 where 子句使用內鏈結

如果需要在使用內鏈結的時候同時使用 where 子句對檢索結果進行篩選, 則需要把 where 子句寫在 on 子句的後邊.

增加 where 子句的方式有好幾種,我們先從最簡單的說起.

第一種增加 wehre 子句的方式, 就是把上述查詢作為子查詢, 用括號封裝起來, 然後在外層查詢增加篩選條件。

執行順序:

from 子句->where 子句->select 子句

也就是說, 兩張表是先按照鏈結列進行了鏈結, 得到了一張新錶, 然後 where 子句對這張新表的行按照兩個條件進行了篩選, 最後, select 子句選出了那些我們需要的列.

此外, 一種不是很常見的做法是,還可以將 where 子句中的條件直接新增在 on 子句中, 這時候 on 子句後最好用括號將鏈結條件和篩選條件括起來.

(3) 結合 group by 子句使用內鏈結

結合 group by 子句使用內鏈結, 需要根據分組列位於哪個表區別對待.

最簡單的情形, 是在內鏈結之前就使用 group by 子句.

但是如果分組列和被聚合的列不在同一張表, 且二者都未被用於鏈結兩張表, 則只能先鏈結, 再聚合.

(4) 自鏈結(self join)

之前的內鏈結, 鏈結的都是不一樣的兩個表. 但實際上一張表也可以與自身作鏈結, 這種連線稱之為自鏈結. 需要注意, 自鏈結並不是區分於內鏈結和外鏈結的第三種鏈結, 自鏈結可以是外鏈結也可以是內鏈結, 它是不同於內鏈結外鏈結的另乙個鏈結的分類方法.

內鏈結與關聯子查詢

(5) 自然鏈結(natural join)

自然鏈結並不是區別於內鏈結和外鏈結的第三種鏈結, 它其實是內鏈結的一種特例–當兩個表進行自然鏈結時, 會按照兩個表中都包含的列名來進行等值內鏈結, 此時無需使用 on 來指定連線條件.

(6)外鏈結(outer join)

內鏈結會丟棄兩張表中不滿足 on 條件的行,和內鏈結相對的就是外鏈結. 外鏈結會根據外鏈結的種類有選擇地保留無法匹配到的行.

按照保留的行位於哪張表,外鏈結有三種形式: 左鏈結, 右鏈結和全外鏈結.

左鏈結會儲存左表中無法按照 on 子句匹配到的行, 此時對應右表的行均為缺失值; 右鏈結則會儲存右表中無法按照 on 子句匹配到的行, 此時對應左表的行均為缺失值; 而全外鏈結則會同時儲存兩個表中無法按照 on子句匹配到的行, 相應的另一張表中的行用缺失值填充.

外鏈結要點 1: 選取出單張表中全部的資訊

外鏈結要點 2:使用 left、right 來指定主表

3.on 子句高階–非等值鏈結

除了使用相等判斷的等值鏈結, 也可以使用比較運算子來進行連線. 實際上, 包括比較運算子(<,<=,>,>=, between)和謂詞運算(like, in, not 等等)在內的所有的邏輯運算都可以放在 on 子句內作為鏈結條件.

(1)非等值自左鏈結(self join)

使用非等值自左鏈結實現排名。

(2)交叉鏈結—— cross join(笛卡爾積)

之前的無論是外鏈結內鏈結, 乙個共同的必備條件就是鏈結條件–on 子句, 用來指定鏈結的條件. 如果你試過不使用這個鏈結條件的鏈結查詢, 你可能已經發現, 結果會有很多行. 在鏈結去掉 on 子句, 就是所謂的交叉鏈結(cross join), 交叉鏈結又叫笛卡爾積, 後者是乙個數學術語. 兩個集合做笛卡爾積, 就是使用集合 a 中的每乙個元素與集合 b 中的每乙個元素組成乙個有序的組合. 資料庫表(或者子查詢)的並,交和差都是在縱向上對錶進行擴張或篩選限制等運算的, 這要求表的列數及對應位置的列的資料型別"相容", 因此這些運算並不會增加新的列, 而交叉連線(笛卡爾積)則是在橫向上對錶進行擴張, 即增加新的列, 這一點和鏈結的功能是一致的. 但因為沒有了on子句的限制, 會對左表和右表的每一行進行組合, 這經常會導致很多無意義的行出現在檢索結果中. 當然, 在某些查詢需求中, 交叉鏈結也有一些用處.

SQL集合運算

集合運算是對輸入的兩個或多個集合進行的運算,最終輸出乙個結果集。t sql支援3種集合運算 並集 union 交集 intersect 和差集 except 集合運算的基本格式為 輸入的集合1 集合運算 輸入的集合2 order by 需要注意的是,集合運算涉及的兩個查詢不能包含order by 子...

SQL集合運算

本系列 t sql基礎 主要是針對t sql基礎的總結。t sql基礎 01.單錶查詢 幾道sql查詢題 t sql基礎 02.聯接查詢 t sql基礎 03.子查詢 t sql基礎 04.表表示式 上篇 t sql基礎 04.表表示式 下篇 t sql基礎 05.集合運算 本系列 t sql基礎 ...

sql的集合運算

交集 內連線 並集全外連線 有的dbms不支援全外連線,比如mysql,可以使用union all來實現全外連線 select from table a inner join table b on table a.id table b.id union allselect from table a ...