上篇咱們說了 SQL 的基本語法,掌握了這些基本語法後,咱們能夠對單表進行查詢及計算分析。可是一個大的系統,每每會有數十上百張表,而業務關係又錯綜複雜。咱們要查的數據每每在好幾張表中,而要從多張表中來獲取信息就須要用到表聯結了。sql
先說說什麼是聯結,聯結就是用一條 SELECT 語句從多個表中查詢數據。經過聯結,讓多張表中的數據互相關聯起來。聯結又分爲內聯結、左外聯結、右外聯結、全外聯結。別怕,我知道有些初學者看到這幾個概念就頭大,不過請繼續日後看,看完後你確定能看明白。在實際中,內聯結和左聯結應該是使用最多的,我幾乎沒用到過右鏈接與全外聯結。code
對初學者來講,在這裏迷惑的緣由是去記這些概念,這是不必的,咱們只要在實際中抱着問題去用一次就能夠徹底掌握了。blog
下面咱們就開始:
咱們有下面三張表,一張訂單表存放訂單頭信息,包括訂單號、訂單類型、訂單數量、訂單狀態信息。排序
一張訂單明細表,存儲訂單的詳細信息。包含訂單號、訂單類型、工序號、工序名稱、工序狀態、物料號、工位號it
一張物料表,存儲訂單工序用到的物料。包含物料號、物料名稱。io
咱們先觀察一下,訂單頭信息中只包含訂單的數量、狀態信息。訂單明細表中包含着訂單的詳細信息,如工序信息,每道工序用到的物料,每道工序的名稱,在哪一個工位操做等信息。假如咱們如今要查詢訂單號、訂單數量、工序號、工序名稱、工位等信息,只有一張表咱們是查不到的,那麼咱們就要把這兩張表結合起來。class
SELECT oh.orderno, oh.order_type, oh.quantity, od.order_line_no, od.order_line_name, od.workcenter FROM order_header oh INNER JOIN order_detail od ON oh.orderno =od.orderno AND oh.order_type=od.order_type
解釋下:咱們用INNER JOIN 表示內鏈接,在 INNER JOIN 後寫上咱們須要關聯的表,oh 和 od 表示別名,方便後面書寫,否則後面咱們就要用到表的全稱來寫了。這裏咱們要關聯到訂單明細表 order_detail,去取出訂單詳細信息。後面跟上 ON 關鍵字,表示條件,這裏 ON 後面有兩個條件。表示咱們經過訂單號和訂單類型來把兩個表中的數據關聯起來,經過訂單表中的訂單號和訂單類型做爲條件來查找訂單明細表中一樣訂單號和訂單類型的訂單的詳細信息。語法
咱們看下結果:nio
能夠看到,咱們查出了訂單 1001 ,1002, 1003, 1004, 1005五個訂單的總數量,各個工序的名稱,在哪一個工位生產等信息。im
細心的讀者可能會注意到,在訂單表中還有一個 1008 的訂單,爲何沒有查出來?那就接着往下看
相比於內聯結,左聯結使用 LEFT JOIN 來表示。咱們先不看概念,咱們直接把剛纔的 SQL 語句改爲左聯結來看一下結果。
SELECT oh.orderno, oh.order_type, oh.quantity, od.order_line_no, od.order_line_name, od.workcenter FROM order_header oh LEFT JOIN order_detail od ON oh.orderno =od.orderno AND oh.order_type=od.order_type;
結果以下圖:
對比內聯結的結果,咱們發現了什麼,咱們發現最下面多了一行,1008 訂單,而1008 後面的幾個字段爲空。咱們看一下訂單明細表會發現沒有 1008 這個訂單。
這樣子咱們就明白了,內聯結是兩張表中都存在才能關聯出來。而左聯結的意思就是咱們的主表中的全部行都會展現出來,若是在聯結的表中找不到對應的,會默認爲 null.
知道了左聯結,右聯結也就清楚了,右鏈接呢會把咱們關聯的表中的全部行都展現出來,無論主表中有沒有匹配的行。右聯結關鍵字爲 RIGHT JOIN
SELECT oh.orderno, oh.order_type, oh.quantity, od.order_line_no, od.workcenter FROM order_header oh RIGHT JOIN order_detail od ON oh.orderno =od.orderno AND oh.order_type=od.order_type;
能夠看到,RIGHT JOIN 把關聯的訂單明細表中的全部行都顯示了出來,可是訂單主表中並無 1006 和 1007 兩個訂單,因此這兩行顯示爲 null
多表聯結就是超過兩張表的聯結,上面咱們關聯了訂單表和訂單明細表,如今咱們想知道每道工序用到的物料,就須要關聯到物料表。咱們看到訂單明細表中有 productid 字段,咱們用這個關聯到 product 表中。同時,後面咱們也用了 ORDER BY 進行排序。
SELECT oh.orderno, oh.order_type, oh.quantity, od.order_line_no, od.workcenter, p.productno, p.product_name FROM order_header oh INNER JOIN order_detail od ON oh.orderno =od.orderno INNER JOIN product1 p ON od.productid =p.ID AND oh.order_type=od.order_type ORDER BY orderno, order_line_no
在使用聯結時必定要注意聯結條件,若是 聯結條件不正確,就會獲得不正確的結果。並且要注意,聯結條件是必須的。
UNION 與 UNION ALL 表示並集,能夠把兩個 SELECT 查詢的結果合併成一個,前提是兩個 SELECT 所查詢的列數量和字段類型一致。不一樣的是 UNION 會去除重複行,而 UNION ALL 不會去除重複行。
若是咱們有兩張表,都存有類似的信息。好比咱們在一個其餘表中也存儲的有訂單信息。舉個栗子,order_header_bak 表中存有以下兩條數據。
咱們用 UNION ALL 試一下
SELECT orderno, order_type, order_status FROM order_header UNION ALL SELECT orderno, order_type, order_status FROM order_header_bak;
看到查出了 8 條信息,1001 訂單有兩條同樣的信息。
咱們用 UNION 試一下
SELECT orderno, order_type, order_status FROM order_header UNION SELECT orderno, order_type, order_status FROM order_header_bak
看到只有 7 條數據了, 1001 訂單隻有一行數據。