[Day15] SQL server like用法 - SQL Server資料庫入門

在這回中將探討SQL server中like的使用方式。

Like

like被用在SQL語法中的where條件。
用來篩選模糊字串。

通常搭配這兩種運算子去實作模糊搜尋條件。

% 代表零或一個或更多的字符
_ 代表一個字符

語法:

1
2
3
SELECT column1, column2, ...
FROM table_name
WHERE columnN LIKE pattern;

常見的模糊字串操作:

LIKE Operator Description
WHERE CustomerName LIKE 'a%' Finds any values that start with "a"
WHERE CustomerName LIKE '%a' Finds any values that end with "a"
WHERE CustomerName LIKE '%or%' Finds any values that have "or" in any position
WHERE CustomerName LIKE '_r%' Finds any values that have "r" in the second position
WHERE CustomerName LIKE 'a_%' Finds any values that start with "a" and are at least 2 characters in length
WHERE CustomerName LIKE 'a__%' Finds any values that start with "a" and are at least 3 characters in length
WHERE ContactName LIKE 'a%o' Finds any values that start with "a" and ends with "o"

範例實作

customers 顧客

products 產品

orders 出貨單

order_details 出貨單明細

實作:想取得產品名稱為P開頭的產品。

1
Select * from products where name like 'P%'

結果:

實作:實作訂單收或簽名為「X中間有一個字X」的人

1
Select * from orders where orders.customer_signature like 'X_X'

結果:
可得到XXX這個人的訂單明細。因為他X與X間隔一個字符。

結論

可以用like在資料庫內做簡易的模糊比對,將一些無法直接對應的數值用這種方式去篩選。

參考資料
https://www.w3schools.com/sql/sql_like.asp

[Day14] SQL server in與not in - SQL Server資料庫入門

在這回中將探討SQL server的in與not in 用法。

IN 與 NOT IN

1.可以使用在where中揀選多個值
2.其實就是多個or的簡化寫法

有點像是以下的感覺:

where 欄位值 in (‘A’,’B’,’C’)
欄位值==’A’ or 欄位值==’B’ or 欄位值==’C’

where 欄位值 not in (‘A’,’B’,’C’)
欄位值!=’A’ or 欄位值!=’B’ or 欄位值!=’C’

1.給予明確數值,篩選是否在這些值中。

1
2
3
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1, value2, ...);

2.可以用在子查詢上,篩選是否在子查詢的數值中

1
2
3
SELECT column_name(s)
FROM table_name
WHERE column_name IN (SELECT STATEMENT);

範例實作

在此,提供一下目前資料表中的測試資料,作為核對。

customers 顧客

products 產品

orders 出貨單

order_details 出貨單明細

實驗

實作:想取得產品名稱為PS5和PS4的產品。

1
Select * from products where name in ('PS5','PS4')

結果:

實作:想取訂單明細中不包含PS4的訂單。

1
2
Select * from order_details 
where product_number not in (Select number from products where name = 'PS4' )

結果:
後方的子查詢結果是[‘P002’],之後因為條件下not in表示是不包含P002,not in (‘P002’)。
所以得到不含PS4的訂單明細。

結論

其實就把in拆成多個or去理解就好。

參考資料
https://www.w3schools.com/sql/sql_in.asp

適當的調整自己心態,不再當個完美主義者

為什麼這麼說呢?因為這社會本來就不是完美的。

完美是個理想狀況。

過往,我在做事總有個目標,就是一次做到最好。因為這樣可以省下未來很多修改的功夫。
但是現在往回看的話,會發現:「欸!這方法好像在現在不算好了,已經過時了。」

在工作上,就如面試,總想拿出很猛的作品,所以一直追加,但後來反而累死了自己。(真實)
(按:就像饒舌歌手都想把自己弄成很屌那樣)

所以,我想改變我的作法了,先規劃最低限度的東西
完美的這目標先擺在一旁,有時間,那就追求;沒時間,那就沒時間(誤)。

這邊講個例子

例子1
某公司開發A產品,公司目標是賺到錢,所以最低限度就是A產品做出來,完成交易。可以完成需求、對方能接受就好。
再來才是雙方提供交流再把他們變得更好。為了更好而畫蛇添足,也不見得帶來好結果。
所以不要一股腦的死做,差異是比較出來的。

例子2
某面試需要有作品集,但實際上不知道面試公司到底要的水平、程度。
就依照自己能力,先規劃出個能夠展示的作品吧!
比如,簡單的留言板、訂單,想追求完美那就再到複雜的電商。

例子3
想做一個遊戲,那就先把你想訴求的點先做出mockup吧!
可玩性還是角色?在做個類似分鏡的結構,最後再找特定領域的人把優化。
如把畫面變好要UI、把效能變好要程式、把角色變好要原畫師。

總結

足球不是一個人能踢的,山不是一日就能堆的,坑不是一次就能填的。

  1. 循序漸進,不然就只會被壓力轟炸而無法繼續下去。
  2. 講求比較實際的作法,嘗試再修正找到一條能通的路。

最後補充,其實寫這種非技術文章可能對技術提升沒什麼用。
但是,想到有人可能會跟我過去一樣執迷不悟,就自己現身說法,希望能改善到看這文章的各位。

[Day13] SQL server Group By 資料分組與聚合函數COUNT(), MAX(), MIN(), SUM(), AVG() - SQL Server資料庫入門

在這回中,將要探討SQL server中的Group By用法,並搭配聚合函數使用。
資料在資料表中都是一列一列的,而分組則是把這些列的某些特徵欄位視為分組依據,並且將他們合為一組,並使用聚合函數就能夠做出簡易的統計。

測試資料

還是一樣,先放上資料表:

customers 顧客

products 產品

orders 出貨單

order_details 出貨單明細

GROUP BY

把相同值列分組成匯總列。
Group By常常與COUNT(), MAX(), MIN(), SUM(), AVG()這些總計有關的語法一起用。

聚合函數
COUNT(column_name):取得欄位資料筆數。(ps.如果想統計整列不管有沒有空值問題可以下 COUNT(*) )
MAX(column_name):取得欄位最大值。
MIN(column_name):取得欄位最小值。
SUM(column_name):取得欄位加總。
AVG(column_name):取得欄位平均值。

語法:

1
2
3
4
5
SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
ORDER BY column_name(s);

實作:統計訂單明細的資料內容。

1
2
3
4
5
Select order_number,sum(price*amount) as 訂單總額 
,avg(price) as 平均商品單價,min(price) as 最低商品單價
,max(price) 最高商品單價,sum(amount) as 總貨量
,count(order_number) as 細項數量
from order_details group by order_details.order_number

結果:
以order_number訂單編號為分組要件,把order_details表中所有重複的order_number都獨立識別成一個群組。
再以這個群組去統計資料。
如下圖,因為資料庫中order_details只有2筆資料,所以把這2筆的order_number嘗試分組,發現都只有A002這個訂單編號,於是就只分成了一組A002的資料,而這組A002資料底下則有2筆資料,可供統計聚合函數COUNT(), MAX(), MIN(), SUM(), AVG()使用。

參考資料
https://www.w3schools.com/sql/sql_groupby.asp
https://ithelp.ithome.com.tw/articles/10218537
https://ithelp.ithome.com.tw/articles/10218055

[Day12] 集合運算union、intersect、except 垂直整合 - SQL Server資料庫入門

在先前我們有使用過的多表查詢都是水平整合的概念,如JOIN [Day10] SQL server Select合併查詢JOIN用法 - SQL Server資料庫入門
以及上篇的子查詢 [Day11] SQL server 子查詢 - SQL Server資料庫入門
而這回,將要探討垂直整合這塊,資料庫提供聯集(union)、交集(intersect)、差集(except)語法可以實作這概念。

測試資料

還是一樣,先放上資料表:
customers 顧客

products 產品

orders 出貨單

order_details 出貨單明細

UNION 聯集(剔除重複)

聯集
被用來結合多個Select語句的結果集(result set)。
與UNION ALL差別在”會剔除重複”,有重複的資料只會顯示其中一筆

限制:
1.欄位的屬性必須一樣
2.每個select語句都必須有相同的欄位數
3.select語句有多個欄位時,欄位的屬性要符合順序

語法:

1
2
3
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

實作:想要把products的price與order_details的price結合,且剔除重複。

1
2
3
select price from products
union
select price from order_details

結果:

UNION ALL 聯集(不剔除重複)

聯集
與UNION差別在”不剔除重複”,有重複的資料會顯示多筆

1
2
3
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

實作:想要把products的price與order_details的price結合,且不剔除重複。

1
2
3
select price from products
union all
select price from order_details

結果:

INTERSECT 交集

交集,將select語句的結果集合併後找出相同的值然後返回結果集。
附註:沒有INTERSECT ALL這種用法
語法:

1
2
3
SELECT column_name(s) FROM table1
INTERSECT
SELECT column_name(s) FROM table2;

實作:取出有訂過訂單的客戶編號,把customers的number與orders的customer_number做交集。

1
2
3
select number from customers
intersect
select customer_number from orders

結果:

EXCEPT 差集

差集,將select語句的結果集合併後找出不相同的值然後返回結果集。
[補充] EXCEPT及只適用於 SQL Server,Oracle的交集則是使用 MINUS,使用方法與EXCEPT一樣; 而MySQL不支援EXCEPT及MINUS,則要使用left join。可參考:http://www.geeksengine.com/database/multiple-table-select/minus-except.php
語法:

1
2
3
SELECT column_name(s) FROM table1
EXCEPT
SELECT column_name(s) FROM table2;

實作:取出”沒有”訂過訂單的客戶編號,把customers的number與orders的customer_number做差集。

1
2
3
select number from customers
except
select customer_number from orders

結果:

小結

發現蠻多細節的語法在不同資料庫的名稱、寫法又會不一樣。
如果不熟某一資料庫,只能盡可能查,否則就得在程式裡面做(雖然較耗記憶體)。
而本篇中練習了聯集(union)、交集(intersect)、差集(except),在使用上蠻直覺的,沒有太困難的操作語法,只要注意一些欄位的屬性排列不要排錯就好。
而我回顧以前,就是使用ORM(Object Relational Mapping),雖然有提供語法,但卻在Select時很難直覺寫出語句,有時甚至不支援還要變成半原生寫法。
所以,以個人經驗覺得原生的SQL語法比較好懂@@。
然後,下篇預告是GROUP BY分組的用法。
參考資料
https://www.w3schools.com/sql/sql_union.asp
https://ithelp.ithome.com.tw/articles/10216761

[Day11] SQL server 子查詢 - SQL Server資料庫入門

在上回 [Day10] SQL server Select合併查詢JOIN用法 - SQL Server資料庫入門 中,我們練習了合併查詢的JOIN。

在這回中,我們主要淺談一下子查詢。
他跟JOIN一樣都可以使用在多表的查詢上。

子查詢

子查詢通常使用在Select的Where子句上。
首先處理的是子查詢條件,才會向外處理外部的主查詢。有點像是寫一個function,然後回傳一個結果再給主程式去跑。

語法:

1
2
3
4
SELECT 欄位名稱1,欄位名稱2,...,欄位名稱n 
FROM 資料表名稱1
WHERE 欄位名稱 =
(SELECT 欄位名稱 FROM 資料表名稱2 WHERE 條件)

1.子查詢要在括號()中。
2.通常子查詢SELECT只會取得單一欄位的值,以便主查詢的欄位進行比較運算。
3.如需排序,子查詢不能使用ORDER BY,只能使用GROUP BY 子句。
4.如果子查詢可以取得多筆資料,在主查詢需使用IN邏輯運算子。

在WHERE使用子查詢主要目的是取得其他資料表紀錄的欄位值來建立WHERE句的條件運算式。

實際演練

目前表中資料

在此,提供一下目前資料表中的測試資料,作為核對。

customers 顧客

products 產品

orders 出貨單

order_details 出貨單明細

實作:想要取得名子為XXX的訂單。

1
2
Select * from orders 
where orders.customer_number = (Select number from customers where customers.name = 'XXX' )

結果:
子查詢的語句只會返回單一一筆的number叫做U001,之後就會變成orders.customer_number = ‘U001’去搜尋,最後得到結果。

實作:想要取得大於平均值的商品列表。

1
2
Select *,(select avg(price) from products) as avg_price from products 
where price > (select avg(price) from products)

結果:
原本想要寫成 where price > avg_price,但發現這樣的寫法不可以,因為前面的這種匿名欄位(原本就不在資料表中的欄位)在where後沒辦法取得,所以又補了一段(select avg(price) from products)。
總之,子查詢也可以用在欄位上。

實作:想取得訂單明細中有商品PS4及PS5的明細。
[補充]EXISTS指令:可以判斷子查詢的結果有沒有回傳資料,若有則會執行查詢中的結果。

1
2
3
Select * from order_details 
where exists
(Select * from products where (products.name = 'PS4' or products.name ='PS5') and products.number = order_details.product_number)

結果:
搜尋order_details表單後用Exists子查詢,用Select取出商品名稱為PS4或PS5的集合,並且這集合的產品編號在訂單明細的產品編號裡。

實作:想取得還沒有下過訂單的顧客。
[補充]IN指令可以檢查是否存在子查詢的資料紀錄中。

1
2
Select * from customers 
where customers.number not in (Select orders.customer_number from orders )

結果:
用子查詢去查orders資料表,得到客戶編號的集合。之後主查詢用not in去篩選不在集合中的顧客編號。
最終得到U002這個沒下訂單的顧客。

小結

在這篇中練習了子查詢的寫法,並且知道子查詢可以放在欄位、或where後,且可以搭配如exists、in等等做法去擴展用法。
可能會找一時間把一些擴展語法如exists、in等等類型的都拉出來獨立講一遍。
下篇預計會是垂直的UNION查詢的做法。

參考資料
https://ithelp.ithome.com.tw/articles/10219497

[Day10] SQL server Select合併查詢JOIN用法 - SQL Server資料庫入門

前言

在上回 [Day9] SQL server查詢語法Select - SQL Server資料庫入門 中,我們練習了一些查詢語法,且都是針對同一張表的查詢。
而在這回中,我們將要開始活用關聯式資料庫的核心用法「JOIN」,透過它實踐合併的查詢。

在這回中我們主要探討五種查詢,並實際來操作:

1.inner Join 內部合併查詢
2.left (outer) Join 左外部合併查詢
3.right (outer) Join 右外部合併查詢
4.full (outer) Join 完全外部合併查詢
5.cross Join 交叉合併查詢

目前表中資料

在此,提供一下目前資料表中的測試資料,作為核對。

關聯圖

customers 顧客

products 產品

orders 出貨單

order_details 出貨單明細

Inner Join 內部合併查詢

內部合併查詢,為兩個表中都有的值才把資料拉出來。
如下圖,就是A、B的交集。

語法:

1
2
3
4
SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name;

實作:對customers以及orders做inner join,得到出貨單與顧客關聯的資料集。
ps.稍微補充一下 orders.number as orders_number 是代表把某東西用as設定別稱

1
2
3
4
Select customers.number,customers.name,orders.number as orders_number 
from customers
inner join orders
on customers.number = orders.customer_number

結果:
可以發現,原本在order表內看不到的客戶名稱name出現了。且customers表中的編號U002並沒出現在表裡,因為在orders表中它找不到相同的值。

Left (outer) Join 左外部合併查詢

取回左邊資料表的所有紀錄,並拉進右邊資料表的值。結果會以左邊資料表為主。

語法:

1
2
3
4
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name;

實作:想要取得顧客名單同時也想知道他們有關的出訂單,對customers以及orders做left join。

1
2
3
4
Select customers.number,customers.name,orders.number as orders_number 
from customers
left join orders
on customers.number = orders.customer_number

結果:
可以發現,customers為主表,所以有客戶即使沒出貨單也被拉出來,而U001這位客戶因為關連到兩筆所以列出兩列。

Right (outer) Join 右外部合併查詢

取回右邊資料表的所有紀錄,並拉進左邊資料表的值。結果會以右邊資料表為主。
其實就是跟左外部查詢一樣,只是表顛倒放而已,通常左邊比較直覺。

語法:

1
2
3
4
SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name;

實作:想要取得訂單,並嘗試抓出顧客名單即使客戶名單消失或為NULL,對customers以及orders做right join。

1
2
3
4
Select customers.number,customers.name,orders.number as orders_number 
from customers
right join orders
on customers.number = orders.customer_number

結果:
可以發現,orders為主表列出了所有訂單2筆A002、A003,並嘗試關聯到顧客。

Full (outer) Join 完全外部合併查詢

full Join(完全外部合併)可以取回左右兩邊資料表的所有紀錄。

語法:

1
2
3
4
5
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name = table2.column_name
WHERE condition;

實作:訂單、顧客名單的左右資料全部合併

1
2
3
4
Select customers.number,customers.name,orders.number as orders_number 
from customers
full join orders
on customers.number = orders.customer_number

結果:
跟inner join比較的話,就是原本因為orders資料表沒有相關資料消失的U002客戶出現了。

Cross Join 交叉合併查詢

交叉連接為兩個資料表間的笛卡兒乘積 (Cartesian product),兩個資料表在結合時,不指定任何條件,即將兩個資料表中所有的可能排列組合出來
語法:

1
Select * From 表A Cross Join 表B;

也就是說表A有5筆紀錄,表B有8筆紀錄,交查合併後會得到5 * 8=40筆的紀錄,如果沒有指名欄位,欄位數就是2個資料表的欄位總數。

實作:取得訂單、顧客名單的所有可能排列組合

1
2
3
Select customers.number,customers.name,orders.number as orders_number 
from customers
cross join orders

結果:
customers目前兩筆資料、orders目前兩筆資料 2x2 = 4 所有可能排列組合。
因為沒用ON去指定,所以會發現顧客U002明明沒訂單卻關聯上了A002、A003訂單。

多組JOIN寫法

簡單來說就是可以依照你的目標去操作各種JOIN得到你要的結果。
大概畫一下圖:

實作:我想得到訂單詳細資料打平的樣子
ps.這種多組JOIN可以用as簡短,以下是全部簡寫。如果為了求好讀可以多打寫字,可以不要用as。

1
2
3
4
Select * from order_details as a
inner join orders as b on a.order_number = b.number
inner join customers as c on c.number = b.customer_number
inner join products as d on a.product_number = d.number

結果:
其實就是把所有的主鍵、外來鍵拉起來而已R。就完全成為正規化前的模樣XDD

總結

在這回中學習了合併查詢的用法JOIN,一般來說都是搭配主鍵、外來鍵去做這些事。
而平常自己實際習慣用INNER JOIN、LEFT JOIN,而FULL JOIN、CROSS JOIN則超少用到。
也許是不太直覺的關係吧XD?
且因為需求都是人想出來的,如果不是計算機專業,一般很少人會想出FULL JOIN、CROSS JOIN。

然後預告一下,下回是子查詢。@@

參考資料:
https://ithelp.ithome.com.tw/articles/10215741
https://www.fooish.com/sql/cross-join.html
https://charleslin74.pixnet.net/blog/post/460066978

[Day9] SQL server查詢語法Select - SQL Server資料庫入門

前言

在上回我們手動對資料庫填充了一些基礎資料:[Day8] SQL server手動寫入資料 - SQL Server資料庫入門
在這回中我們要利用建立好的資料庫來練習查詢語法。

目前表中資料

先看一下資料庫中的資料:
customers 顧客

products 產品

orders 出貨單

order_details 出貨單明細

SQL SELECT 語法實踐

select為資料庫查詢的語法,被用來選取資料表中的資料。
當語法執行後,資料會被儲存在一個結果表(result table),即結果集(result-set)。

1.選擇表中的部分欄位

1
2
SELECT column1, column2, ...
FROM table_name;

實作:查詢orders中的編號、寄送日、寄送地址

1
Select number,shipping_date,shipping_address from orders

結果:

2.選擇表中的全部欄位

1
SELECT * FROM table_name; 

實作:查詢orders中所有欄位

1
Select * from orders

結果:

SQL SELECT DISTINCT 語法實踐

被用來取得非重複列的集合。

1
2
SELECT DISTINCT column1, column2, ...
FROM table_name;

實作:查詢order_details的order_number,並回傳非重複的列

1
Select DISTINCT order_number from order_details 

結果:

實作:查詢order_details的order_number、id,並回傳非重複的列

1
Select DISTINCT id,order_number from order_details 

結果:
會發現跟上面的只搜尋order_number多增加一列,因為id與order_number這樣視為一列

SQL WHERE 語法

用可來限制Select的條件、過濾資料。
可使用的限制條件:

Operator Description
= Equal
> Greater than
< Less than
>= Greater than or equal
<= Less than or equal
<> Not equal. Note: In some versions of SQL this operator may be written as !=
BETWEEN Between a certain range
LIKE Search for a pattern
IN To specify multiple possible values for a column

語法:

1
2
3
SELECT column1, column2, ...
FROM table_name
WHERE condition;

實作:查詢order_details,並且限制單價為10000的資料

1
Select * from order_details  where price = '10000'

結果:

實作:查詢order_details,並且限制產品編號為P001、P002的結果

1
Select * from order_details  where product_number IN ('P001','P002')

結果:

SQL AND, OR and NOT 語法

在使用where時,我們可以用AND、 OR、 NOT去組合我們理想的條件。
AND:組合多個條件,全為TURE回傳

1
2
3
SELECT column1, column2, ...
FROM table_name
WHERE condition1 AND condition2 AND condition3 ...;

OR:組合多個條件,符合其中一個條件都算在資料集中,最後回傳。

1
2
3
SELECT column1, column2, ...
FROM table_name
WHERE condition1 OR condition2 OR condition3 ...;

NOT:想排除某條件

1
2
3
SELECT column1, column2, ...
FROM table_name
WHERE NOT condition;

實作:查詢order_details,並且限制amount為2或total為30000的結果

1
Select * from order_details where amount = '2' or total = '30000'

結果:

實作:查詢order_details,並且限制amount為2或total為30000,且id不為2的結果

1
Select * from order_details where amount = '2' or total = '30000' and NOT id = '2'

結果:

SQL ORDER BY 語法

可用來排序Select結果表的結果集合,透過欄位可以遞增、遞減。

1
2
3
SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC|DESC;

實作:查詢order_details,並把id遞減排序

1
Select * from order_details order by id desc

結果:

SQL TOP 語法

取得前幾筆資料,在MSSQL中則是用TOP;MYSQL用LIMIT,似乎每個DB都有不同的標準。

1
2
3
SELECT TOP number|percent column_name(s)
FROM table_name
WHERE condition;

實作:查詢order_details,前一筆資料

1
Select TOP 1 * from order_details 

結果:

SQL NULL Values 語法

可以用來篩選欄位是否為空值(未填充)。
為空:

1
2
3
SELECT column_names
FROM table_name
WHERE column_name IS NULL;

不為空:

1
2
3
SELECT column_names
FROM table_name
WHERE column_name IS NOT NULL;

實作:查詢order_details,remarks不為空的結果

1
Select * from order_details where remark IS NOT NULL

結果:

小結

在這回中大量練習了表單的查詢,發現其實還蠻單純的,並不會特別難或什麼。
在下回中會開始練習跨表的搜尋JOIN。

參考資料
https://ithelp.ithome.com.tw/articles/10214938
https://www.w3schools.com/sql/sql_select.asp
https://www.w3schools.com/sql/sql_where.asp

[Day8] SQL server手動寫入資料 - SQL Server資料庫入門

在上回 [Day7] SQL server資料庫關聯 - SQL Server資料庫入門 中,我們拉完了訂單表單的資料庫關聯。
在這回就要實際的將資料寫入。

訂單圖

資料表關聯圖

(Ps.如果你想知道怎麼把訂單圖轉成那四張資料表可以看 [Day5] 規劃資料表,透過資料庫正規化 - SQL Server資料庫入門 )

我們預計將填入以下資料:

將資料手動寫入

1.customers表 > 右鍵 Edit Top 200 Rows 叫出編輯視窗

2.將資料輸入即可,就像Excel那樣

3.products表也一樣

4.orders表也一樣

5.order_details表也一樣,而id設定自動遞增,所以不用填寫會自動補。

6.這樣就就完成把資料手動寫入了。

結語

這回主要是練習將資料手動寫入,並看看是否會有問題。
再來就是SQL語法的撰寫了,會以比較常見>進階>特殊這樣去前進。
下回預計是用語法寫入的話該怎麼寫。

[Day7] SQL server資料庫關聯 - SQL Server資料庫入門

在上回中 [Day6] SQL server資料表建立 - SQL Server資料庫入門 我們建立了正規化後的資料表進資料庫。
在這回中我們要知道資料庫中的關聯關係,並且拉好SQL server中表的主鍵、外來鍵關聯。

一對一(One to One):

有A、B兩個table裡面各自存在一筆記錄,可以使用其主鍵,對應至另一個table的一筆記錄。
如下圖,students_public裡的sid 107000001 在students_private只會出現1筆;students_private裡的sid 107000001在students_public也只會出現1筆。

一對多(One to Many):

如depdepartments的一筆id可以對應到students多筆的dept_id。
所以depdepartments對students是一對多。
相對的,students多筆的dept_id可以對應到depdepartments的一筆id。
所以students對depdepartments是多對一。

多對多(Many to Many):

一個 A 是否會有多個 B?
一個 B 是否會有多個 A?
兩者皆是,就是多對多

以下面例子,
一個文章是否有多個標籤?ANS:是
一個標籤是否有多個文章?ANS:是

這邊稍微解講一下,多對多可能會呈現以下的圖表情況。
posts透過一張中介的表(intermediary table)對應到tags
tags透過一張中介的表(intermediary table)對應到posts
則post與tags為多對多。

(PS.基本上在2NF、3NF時就會不自覺得做出這種表。)

可以參考 [Day5] 規劃資料表,透過資料庫正規化 - SQL Server資料庫入門

ps.圖片來源參考自參考資料。

拉資料表關聯

1.建立資料表視圖

2.選取要呈現的表

3.顯示我們剛剛建立的4張表

4.拉關聯
對order_details來說,product_number是外來鍵,而主鍵則是指向products的number。
從products的number拖曳到order_details的product_number即可完成關聯,會跳出視窗點確認後點確定即可。

5.把剩下的也拉完
對orders來說,customer_number是外來鍵,而主鍵則是指向customers的number。
對order_details來說,order_number是外來鍵,而主鍵則是指向orders的number。
如此一來就完成手動關聯了。

6.分析一下資料庫中的表的關聯性

customers、orders
一個顧客有多個訂單?是
一個訂單是否有多個顧客?否
所以customers對orders是一對多

orders、order_details
一個訂單是否有多個訂單明細?是
一個明細是否有多個訂單?否
所以orders對order_details是一對多

orders與products,中間媒介order_details
一個訂單是否有多個產品?是
一個產品是否有多個訂單?是
所以orders對products是多對多

結語

在一對一、一對多,我們可以很直覺的知道。
而多對多時可能需要想:
一個 A 是否會有多個 B?
一個 B 是否會有多個 A?
如果回答都是”是”那就是多對多,少一個就是一對多或多對一。

此外,我覺得在規劃時好像不太需要知道一對一、一對多、多對多,只是如果知道在拆表上可能會更快。
因為在2NF、3NF時會不自覺完成,只要知道主鍵、外來鍵即可。

在下回預計會將資料填入資料庫中。

參考資料:
https://medium.com/pierceshih/%E7%AD%86%E8%A8%98-%E8%B3%87%E6%96%99%E9%97%9C%E8%81%AF%E7%9A%84%E4%B8%89%E7%A8%AE%E9%97%9C%E4%BF%82-245152c093da
https://notes.andywu.tw/2018/%E8%B3%87%E6%96%99%E5%BA%AB-%E9%97%9C%E8%81%AF%E4%BB%8B%E7%B4%B9-%E4%B8%80%E5%B0%8D%E4%B8%80%E3%80%81%E4%B8%80%E5%B0%8D%E5%A4%9A%E3%80%81%E5%A4%9A%E5%B0%8D%E5%A4%9A/
https://ithelp.ithome.com.tw/articles/10214381