這是線上平台課程的筆記內容,就是讓自己方便複習用。
老師講課的進度掌握得很好,教得也很淺寫易懂。
線上平台課程內有提供 SQL套件,如果有興趣的朋友一定要去支持老師的課程。
這樣才能取得老師提供的套件包做練習使用。
如果有想要知道老師的課程,再詢問我。
CH6 JOIN 將多個表連結再一起。
資料庫顯示
Table顯示
現在假設有兩個Table
Customers orders
_________ _______
Customerid customerid
現在我們想將這兩者連接再一起,可以透過工具連接。
看是要一對多,或者一對一。
每張表都要ID字段,方便進行連接。
內部加入兩個表
INNER JOIN
這是一種連接表格的方法,這些表格會知道那些密鑰[PK]的所有紀錄,並拉回來
如果你有兩個表的客戶ID等欄位相同,該如何顯示。
table_name.field_name
例如:
customers.customerid
基本的連接語法
從表1中搜尋你的欄位,然後在內部連接上表2
SELECT 欄位
FROM table1
INNER JOIN table2 ON table1.欄位 = table2.欄位
SELECT 欄位名稱
FROM <table1>
JOIN table2 ON table1.欄位 = table2.欄位
INNER JOIN 可以只打JOIN,因為INNER是預設值。
練習,先將資料庫連接起來。
SELECT companyname, orderdate, shipcountry
FROM customers
INNER JOIN orders ON orders.customerid =customers.customerid;
這個動作將會把與客戶相關的訂單拉回到這邊。
對於customers這張表而言,他只有companyname的欄位。
後面的orderdate,shipcountry都沒有。
所以要透過INNER JOIN 將有這兩個資料的orders表拉進來做搜尋。
而對應的連接方式就是讓兩個用有相同對照資料的customerid做比對黏合。
LAB 現在來進行連接。我們要連接employee以及orders
搜尋結果將包含所有訂單的first name ,last name,orderdate 。
這邊的重點在於員工的姓名、所以兩邊的連接需要有名稱可以進行。
SELECT firstname, lastname, orderdate
FROM employees
INNER JOIN orders ON orders.employeeid = employees.employeeid;
LAB2 連接products 到suppliers
顯示資料為companyname,unitprice,unitsinstock
將商品連接到供應商,看看供應商的產品單價和庫存量。
兩邊可以連接起來的對照是supplierid
SELECT companyname, productname, unitprice, unitsinstock
FROM suppliers
INNER JOIN products ON products.supplierid = suppliers.supplierid;
這邊可以看到甚麼供應商提供了甚麼產品,單價是多少,我們數量還有多少。
這個時候還可以在排序一下。
SELECT companyname, productname, unitprice, unitsinstock
FROM suppliers
INNER JOIN products ON products.supplierid = suppliers.supplierid
ORDER BY companyname ASC;
如果有看懂資料庫的連接表對應,會讓你比較好了解如何去INNER JOIN。
多表的內部連接。
基本作法是添加一個具有相同內連接的附加行。
但這張表示表3
SELECT 欄位
FROM table1
INNER JOIN table2 ON table1.欄位 = table2.欄位
INNER JOIN table3 ON table3.欄位 = table1.欄位
SELECT 欄位名稱
FROM <table1>
JOIN table2 ON table1.欄位 = table2.欄位
JOIN table3 ON table3.欄位 = table1.欄位
這邊需要companyname、orderdate、productid、unitprice、quantity
SELECT companyname, orderdate, productid, unitprice, quantity
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
INNER JOIN order_details ON order_details.orderid = orders.orderid ;
這邊先customers連接orders表,再透過orders表與order_details的連接。
進行INNER JOIN的動作。
LAB 哪家公司訂購了甚麼東西,訂購了多少。顯示單價
SELECT companyname, productname, unitprice, quantity
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
INNER JOIN order_details ON order_details.orderid = orders.orderid
INNER JOIN products ON products.productid = order_details.productid ;
因為unitprice有多個地方有,所以如果只是打這樣,會出現錯誤。
不知道要讀取那邊的。
這邊指定要從order_details裡面取得資料。
SELECT companyname, productname, order_details.unitprice, quantity
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
INNER JOIN order_details ON order_details.orderid = orders.orderid
INNER JOIN products ON products.productid = order_details.productid ;
LAB2 希望增加類別,讓我們可以方便尋找。
SELECT companyname, categoryname, productname, order_details.unitprice, quantity
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
INNER JOIN order_details ON order_details.orderid = orders.orderid
INNER JOIN products ON products.productid = order_details.productid
INNER JOIN categories ON categories.categoryid = products.categoryid;
這邊要加上條件,我們只要海鮮類的產品。 categoryname = 'Seafood';
SELECT companyname, categoryname, productname, (order_details.unitprice * quantity) AS Total
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
INNER JOIN order_details ON order_details.orderid = orders.orderid
INNER JOIN products ON products.productid = order_details.productid
INNER JOIN categories ON categories.categoryid = products.categoryid
WHERE categoryname = 'Seafood' AND (order_details.unitprice * quantity) >= 500
ORDER BY total ASC;
如果要維持原狀,不特別顯示賣出金額
SELECT companyname, categoryname, productname, order_details.unitprice, quantity
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
INNER JOIN order_details ON order_details.orderid = orders.orderid
INNER JOIN products ON products.productid = order_details.productid
INNER JOIN categories ON categories.categoryid = products.categoryid
WHERE categoryname = 'Seafood' AND (order_details.unitprice * quantity) >= 500;
左連接
LEFT JOIN
把第二張表拉回第一張,然後吻合的資料以第二張為主。
若是沒有找到吻合的資料,則從第一張表當中顯示少的數據。
SELECT 欄位
FROM 表
LEFT JOIN table2 ON table1.欄位名 = table2.欄位名;
這邊要想一下table1目前在table2的左側。
所以不論是否紀錄,所有數據都會返回table1
看看客戶訂單,然後帶回公司名稱&訂單ID
SELECT companyname, orderid
FROM customers
LEFT JOIN orders ON orders.customerid=customers.customerid;
這邊注意拉到最後面。
會看到兩個NULL,表示未下訂單的客戶公司。
這邊的831 832是特別拿出來顯示的。原本的orderid就只有830筆資料。
LEFT JOIN,這邊以customers為主,要把所有公司列出來。
沒有的資料就NULL。這也是造就了多出兩筆紀錄的原因。
這邊如果用RIGHT JOIN 結果就不一樣。下一章會說明
但這邊用RIGHT JOIN就是以右邊的為主。
也就是以order為主。 Orderid那邊一共就是830筆資料。
若以order為主。那沒有訂購的公司就不關order這張表的事。
這邊加上條件orderid是NULL的列出來
SELECT companyname, orderid
FROM customers
LEFT JOIN orders ON orders.customerid=customers.customerid;
WHERE ordered IS NULL;
現在在產品products & 訂單細節order_details 進行左連接。
SELECT productname, orderid
FROM products
LEFT JOIN order_details ON order_details .productid = products .productid;
接著使用NULL,看看是否有任何尚未被訂購的商品。
現階段表示每個產品都有被訂購過。
右連接 RIGHT JOIN
與左連接相反,這邊將是以第一張表為主要條件。
SELECT 欄位
FROM 表
RIGHT JOIN table2 ON table1.欄位名 = table2.欄位名;
SELECT companyname, orderid
FROM orders
RIGHT JOIN customers ON customers.customerid = orders.customerid;
加上NULL的條件。
LAB 看一下有沒有為客戶做過DEMO
customercustomerdemo (RIGHT表)
customers
customercustomerdemo .customerid 有沒有做過的紀錄。
這邊看起來全部都是NULL,表示沒有。
完全加入
FULL JOIN
他連動了兩張連接的表。即使時某一張表缺乏紀錄。
SELECT 欄位
FROM 表
FULL JOIN table2 ON table1.欄位名 = table2.欄位名;
現在連接customers & orders的表
顯示companyname 、 orderid的資料。
這個方式對於找尋沒有訂單的客戶相當有用。
不管怎麼樣使用,找NULL都超快。
SELECT companyname, orderid
FROM customers
FULL JOIN orders ON orders.customerid = customers.customerid;
SELECT companyname, orderid
FROM orders
FULL JOIN customers ON orders.customerid = customers.customerid;
有發現嗎,之前的LEFT JOIN 與 RIGHT JOIN。
會依照我們輸入的順序,決定依哪張表為主。
但FULL JOIN就是不管,我兩邊全部的表都要抓出來顯示。
所以我們表的順序反倒變成沒那麼嚴重。
LAB 在產品&類別中做一個完整的聯合。
products, categories
SELECT productname, categoryname
FROM products
FULL JOIN categories ON categories.categoryid = products.categoryid;
自我加入
SELF JOIN
表示連接回自身
語法比較不一樣
SELECT 欄位名稱
FROM table1 T1, table2 T2
WHERE 條件;
這邊是必須使用別名的方式進行,不然沒有辦法自我加入。
因為你查詢時會發現衝突的問題。
上述就是將table1命名為 T1 , table2命名為T2的做法。
找到在同一個城市內的所有客戶。
SELECT C1.companyname, C2.companyname, C1.city
FROM customers C1, customers C2
WHERE C1.city=C2.city AND C1.customerid>C2.customerid;
City是平等的。
然後部要讓同一個公司自身的匹配重複。
LAB 找尋同一個國家中的供應商
SELECT S1.companyname, S2.companyname, S1.country
FROM suppliers S1, suppliers S2
WHERE S1.country=S2.country;
每一筆都是同屬這個國家的供應商名稱
用country來排序,我們可以看到,就是一樣的資料再作排列組合而已。
若是不要讓一樣的供應商對在一起。
我們才要下第二個條件。
AND S1.supplierid>S2.supplierid;
簡單的來說就是去掉S1.supplierid的第一個欄位,
以及S2.supplierid的最後一個欄位。
SELECT S1.companyname, S2.companyname, S1.country
FROM suppliers S1, suppliers S2
WHERE S1.country=S2.country AND S1.supplierid>S2.supplierid;
最後排序一下,就完成了。
SELECT S1.companyname, S2.companyname, S1.country
FROM suppliers S1, suppliers S2
WHERE S1.country=S2.country AND S1.supplierid>S2.supplierid
ORDER BY S1.country ASC;
<本篇完˙>
第一篇: IT讀書室-SQL語法學習- postgre安裝與匯入
第四篇: IT讀書室-SQL語法學習- 中間的SELECT語句
如果筆記造成任何法律或者侵權的問題,作者會立即將筆記下架。