上篇我們說(shuō)了 SQL 的基本語(yǔ)法辆亏,掌握了這些基本語(yǔ)法后,我們可以對(duì)單表進(jìn)行查詢及計(jì)算分析符相。但是一個(gè)大的系統(tǒng)拆融,往往會(huì)有數(shù)十上百?gòu)埍恚鴺I(yè)務(wù)關(guān)系又錯(cuò)綜復(fù)雜啊终。我們要查的數(shù)據(jù)往往在好幾張表中镜豹,而要從多張表中來(lái)獲取信息就需要用到表聯(lián)結(jié)了。
先說(shuō)說(shuō)什么是聯(lián)結(jié)蓝牲,聯(lián)結(jié)就是用一條 SELECT 語(yǔ)句從多個(gè)表中查詢數(shù)據(jù)趟脂。通過(guò)聯(lián)結(jié),讓多張表中的數(shù)據(jù)互相關(guān)聯(lián)起來(lái)例衍。聯(lián)結(jié)又分為內(nèi)聯(lián)結(jié)昔期、左外聯(lián)結(jié)、右外聯(lián)結(jié)佛玄、全外聯(lián)結(jié)硼一。別怕,我知道有些初學(xué)者看到這幾個(gè)概念就頭大梦抢,不過(guò)請(qǐng)繼續(xù)往后看般贼,看完后你肯定能看明白。在實(shí)際中奥吩,內(nèi)聯(lián)結(jié)和左聯(lián)結(jié)應(yīng)該是使用最多的哼蛆,我?guī)缀鯖](méi)用到過(guò)右連接與全外聯(lián)結(jié)。
對(duì)初學(xué)者來(lái)說(shuō)霞赫,在這里迷惑的原因是去記這些概念腮介,這是沒(méi)必要的,我們只要在實(shí)際中抱著問(wèn)題去用一次就可以完全掌握了端衰。
下面我們就開(kāi)始:
我們有下面三張表叠洗,一張訂單表存放訂單頭信息,包括訂單號(hào)旅东、訂單類型惕味、訂單數(shù)量、訂單狀態(tài)信息玉锌。
一張訂單明細(xì)表名挥,存儲(chǔ)訂單的詳細(xì)信息。包含訂單號(hào)主守、訂單類型禀倔、工序號(hào)榄融、工序名稱、工序狀態(tài)救湖、物料號(hào)愧杯、工位號(hào)
一張物料表,存儲(chǔ)訂單工序用到的物料鞋既。包含物料號(hào)力九、物料名稱。
內(nèi)聯(lián)結(jié)
我們先觀察一下邑闺,訂單頭信息中只包含訂單的數(shù)量跌前、狀態(tài)信息。訂單明細(xì)表中包含著訂單的詳細(xì)信息陡舅,如工序信息抵乓,每道工序用到的物料,每道工序的名稱靶衍,在哪個(gè)工位操作等信息灾炭。假如我們現(xiàn)在要查詢訂單號(hào)、訂單數(shù)量颅眶、工序號(hào)蜈出、工序名稱、工位等信息涛酗,只有一張表我們是查不到的铡原,那么我們就要把這兩張表結(jié)合起來(lái)。
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 表示內(nèi)連接煤杀,在 INNER JOIN 后寫上我們需要關(guān)聯(lián)的表眷蜈,oh 和 od 表示別名沪哺,方便后面書寫沈自,不然后面我們就要用到表的全稱來(lái)寫了。這里我們要關(guān)聯(lián)到訂單明細(xì)表 order_detail辜妓,去取出訂單詳細(xì)信息枯途。后面跟上 ON 關(guān)鍵字,表示條件籍滴,這里 ON 后面有兩個(gè)條件酪夷。表示我們通過(guò)訂單號(hào)和訂單類型來(lái)把兩個(gè)表中的數(shù)據(jù)關(guān)聯(lián)起來(lái),通過(guò)訂單表中的訂單號(hào)和訂單類型作為條件來(lái)查找訂單明細(xì)表中同樣訂單號(hào)和訂單類型的訂單的詳細(xì)信息孽惰。
我們看下結(jié)果:
可以看到晚岭,我們查出了訂單 1001 ,1002勋功, 1003坦报, 1004库说, 1005五個(gè)訂單的總數(shù)量,各個(gè)工序的名稱片择,在哪個(gè)工位生產(chǎn)等信息潜的。
細(xì)心的讀者可能會(huì)注意到,在訂單表中還有一個(gè) 1008 的訂單字管,為什么沒(méi)有查出來(lái)啰挪?那就接著往下看
左聯(lián)結(jié)
相比于內(nèi)聯(lián)結(jié),左聯(lián)結(jié)使用 LEFT JOIN 來(lái)表示嘲叔。我們先不看概念亡呵,我們直接把剛才的 SQL 語(yǔ)句改成左聯(lián)結(jié)來(lái)看一下結(jié)果。
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;
結(jié)果如下圖:
對(duì)比內(nèi)聯(lián)結(jié)的結(jié)果借跪,我們發(fā)現(xiàn)了什么政己,我們發(fā)現(xiàn)最下面多了一行,1008 訂單掏愁,而1008 后面的幾個(gè)字段為空歇由。我們看一下訂單明細(xì)表會(huì)發(fā)現(xiàn)沒(méi)有 1008 這個(gè)訂單。
這樣子我們就明白了果港,內(nèi)聯(lián)結(jié)是兩張表中都存在才能關(guān)聯(lián)出來(lái)沦泌。而左聯(lián)結(jié)的意思就是我們的主表中的所有行都會(huì)展示出來(lái),如果在聯(lián)結(jié)的表中找不到對(duì)應(yīng)的辛掠,會(huì)默認(rèn)為 null.
右聯(lián)結(jié)
知道了左聯(lián)結(jié)谢谦,右聯(lián)結(jié)也就清楚了,右連接呢會(huì)把我們關(guān)聯(lián)的表中的所有行都展示出來(lái)萝衩,不管主表中有沒(méi)有匹配的行回挽。右聯(lián)結(jié)關(guān)鍵字為 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 把關(guān)聯(lián)的訂單明細(xì)表中的所有行都顯示了出來(lái)猩谊,但是訂單主表中并沒(méi)有 1006 和 1007 兩個(gè)訂單千劈,所以這兩行顯示為 null
多表聯(lián)結(jié)
多表聯(lián)結(jié)就是超過(guò)兩張表的聯(lián)結(jié),上面我們關(guān)聯(lián)了訂單表和訂單明細(xì)表牌捷,現(xiàn)在我們想知道每道工序用到的物料墙牌,就需要關(guān)聯(lián)到物料表。我們看到訂單明細(xì)表中有 productid 字段暗甥,我們用這個(gè)關(guān)聯(lián)到 product 表中喜滨。同時(shí)鹦马,后面我們也用了 ORDER BY 進(jìn)行排序练湿。
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
注意
在使用聯(lián)結(jié)時(shí)一定要注意聯(lián)結(jié)條件,如果 聯(lián)結(jié)條件不正確嚼隘,就會(huì)得到不正確的結(jié)果。而且要注意辜膝,聯(lián)結(jié)條件是必須的陌凳。
UNION 與 UNION ALL
UNION 與 UNION ALL 表示并集,可以把兩個(gè) SELECT 查詢的結(jié)果合并成一個(gè)内舟,前提是兩個(gè) SELECT 所查詢的列數(shù)量和字段類型一致合敦。不同的是 UNION 會(huì)去除重復(fù)行,而 UNION ALL 不會(huì)去除重復(fù)行验游。
如果我們有兩張表充岛,都存有相似的信息。比如我們?cè)谝粋€(gè)其他表中也存儲(chǔ)的有訂單信息耕蝉。舉個(gè)栗子崔梗,order_header_bak 表中存有如下兩條數(shù)據(jù)。
我們用 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 條數(shù)據(jù)了, 1001 訂單只有一行數(shù)據(jù)场躯。