close

這是線上平台課程的筆記內容,就是讓自己方便複習用。

老師講課的進度掌握得很好,教得也很淺寫易懂。

線上平台課程內有提供 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的欄位。

後面的orderdateshipcountry都沒有。

所以要透過INNER JOIN 將有這兩個資料的orders表拉進來做搜尋。

而對應的連接方式就是讓兩個用有相同對照資料的customerid做比對黏合。


LAB 現在來進行連接。我們要連接employee以及orders

搜尋結果將包含所有訂單的first name last nameorderdate

這邊的重點在於員工的姓名、所以兩邊的連接需要有名稱可以進行。

 

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.欄位

 

這邊需要companynameorderdateproductidunitpricequantity

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這張表的事。

 


這邊加上條件orderidNULL的列出來

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查詢

第三篇:  IT讀書室-SQL語法學習- WHERE條件

第四篇:  IT讀書室-SQL語法學習- 中間的SELECT語句

 


如果筆記造成任何法律或者侵權的問題,作者會立即將筆記下架。

 

 

 

 

 

arrow
arrow
    全站熱搜

    IT001 發表在 痞客邦 留言(0) 人氣()