資料庫設計 - 有效的使用系統資料 - 第五章 SQL 語法
單元 1 Select 撈取資料庫資料的關鍵字
select <欄位名稱>
from <資料庫.table 名稱>
where <條件>;
select *
from orders
where costomerid = 3;
在 workbench 要先指定 orders 資料庫
orders 變成粗體
如果指定到 sys 資料庫會發生 error
補充:
-
單純寫 select 就是列印
-
資料量大時避免使用 *,要寫出欄位名稱
-
搜尋資料時,加入條件增加搜尋效率,條件語法
-
where
select * from orders where customerid = 10;Django 語法
Orders.objects.get(customer_id = 10) -
limit
select * from orders limit 10;Django 語法
returns the first 5 objects (
LIMIT 10):**
>>>** Orders**.**objects**.**all()[:10]This returns the sixth through tenth objects (
OFFSET 5 LIMIT 10):**
>>>** Orders**.**objects**.**all()[5:15]Generally, slicing a
[QuerySet]returns a new[QuerySet]– it doesn’t evaluate the query. An exception is if you use the “step” parameter of Python slice syntax. For example, this would actually execute the query in order to return a list of every second object of the first 10:**
>>>** Orders**.**objects**.**all()[:10:2] -
and
select * from orders where customerid = 10 and employeeid = 4;Django 語法
Orders.objects.filter(customer_id = 10, employee_id = 4)
-
作業練習
找出 customerid = 87, shipperid = 3 的資料
Django 語法
Orders.objects.filter(customer_id = 87, shipper_id = 3)
單元 2 Join 多個表格連接在一起的做法
利用主鍵與外鍵,把 table 串在一起做搜尋:將兩個 table 結合在一起,在 where 設定結合條件來執行
select * from A, B
where A.id = B.A_id;
Django 語法
B.objects.all().prefetch_related('A_id')
練習
1. Orders & OrderDetails 結合
SELECT * FROM orders, orderdetails
WHERE orders.orderid = orderdetails.orderid;
Django 語法
OrderDetails.objects.all().prefetch_related('orders_id')
2. Orders & Customers 結合
select * from orders, customers
where orders.CustomerID = customers.CustomerID;
Django 語法
Orders.objects.all().prefetch_related('customer_id')
單元 3 排序
order by
- asc 小 → 大
- desc 大 → 小
select * from A
order by column1 desc;
練習
-
排序員工的生日
SELECT * FROM employees order by birthdate asc;Django 語法
Employees.objects.order_by('-birthdate') -
產品價格 大 → 小 排序
select * from products order by price desc;Django 語法
Products.objects.order_by('-price')- price 前的 ‘-’ 代表 descending
- 沒有 ‘-’ 代表 ascending
-
員工生日 小 → 大
SELECT * FROM employees order by birthdate asc;Django 語法
Employees.objects.order_by('birthdate')
單元 4 將特定欄位中相同的資料作為分組
Group by
-
資料分組
-
當我們搜尋的欄位中,包含函數的運算時,我們就會使用 group by
-
List Table
item price 餅乾 20 洗髮精 100 餅乾 20
Django 語法是 values()
sum() 函式
如果不用 group by
會將 price 價格加總為一個數字 = 140
select item, sum(price)
from list;
select item, sum(price)
from list
group by item;
試算所有供應商提供的報價總和
SELECT supplierid, sum(price) FROM products
group by SupplierID;
作業練習
找出賣最好的商品
- 看 orderdetail 的相同 product 總金額最高的
- 將 orderdetails 與 products table join
- group by productid 查看其 sum(price)
- 按照高到低排序 order by sum(price) desc
SELECT orderdetails.ProductID, products.ProductName, sum(price) FROM orderdetails, products
where orderdetails.ProductID = products.ProductID
group by products.ProductID
order by sum(price) desc;
單元 5 資料分組後加入條件
having
過濾條件,控制哪些組可以出現在最後結果
SELECT orderdetails.ProductID, products.ProductName, sum(price) FROM orderdetails, products
where orderdetails.ProductID = products.ProductID
group by products.ProductID
having sum(price) > 500
order by sum(price) desc;
having 要放在最後
但如果有 order by ,要放在最後是因為,撈出來的資料呈現,要按照 order by 排序出最後的結果。
練習 having > 400 or 300
單元 6 欄位名字太長,表單名字太複雜,暫時取暱稱
as
用來指定表格別名或欄位別名
select a.col_1 as name //(結果呈現會用 name 呈現)
from Tabel_1 as a, Table_2 as b
where a.id = b.table1_id
練習
可以不輸入 as 即可使用
-
改變 table 名稱
select * from orderdetails d, orders o where o.OrderID = d.OrderID; -
改變 column 名稱
select o.orderid order_id from orderdetails d, orders o where o.OrderID = d.OrderID;orderid → order_id
-
數量 * 價格,金額最高的產品是哪一個
SELECT p.ProductID product_id, p.productName product_name, sum(p.price * od.quantity) Total FROM products p, orderdetails od where p.ProductID = od.ProductID group by product_id order by Total desc;
單元 7 不曉得完整、精確資料內容,也可以找出大概可能的結果
like
- %
- 可以找出相同模式的資料
select * from Table
where name like 'C%';
練習
SELECT * FROM employees
where LastName like '%a%';
SELECT * FROM employees
where LastName like 'D%';
單元 8 搜尋出特定範圍的日期或數字資料
between … and
- between 可以找出一個範圍內的資料
select *
from Table
where <欄位名稱> between 1 and 10;
SELECT * from products
where price between 20 and 30;
SELECT * FROM orders
where orderdate between '1996-07-08 00:00:00' and '1996-07-15 00:00:00';
Django 語法
用 range=(start, end)
filter(欄位名稱__range=(start, end))
單元 9 元素比較
in/not in
- 找出符合 in 元素中的資料
select *
from TABLE
where <欄位名稱> in (5, 8);
練習
-
找出 product table 中 product id 為 2 或 4 的資料
SELECT * FROM orders.products where productid in (2, 4); -
找出 product table 中 categoryid 不為 2 跟 4 的資料
SELECT * FROM orders.products where CategoryID not in (2, 4) order by CategoryID asc;
單元 10 子查詢
- 在一個 SQL 查詢敘述中,再放入另一個 SQL 查詢
- 子查詢要用括弧包起來()
- 在使用子查詢的時候也可以使用外部 SQL 的 Table 與欄位
-
子查詢放在 from
子查詢的結果為一張 table,所以直接當 table 使用
select * from (子查詢) as <名稱> where <條件>; -
子查詢放在 where 條件
此處之(子查詢)可以使用 Table_1 欄位的資料
select * from Table_1 where <欄位名稱> in (子查詢); -
子查詢放在 select
查詢出來的結果當成一個欄位
select *, (子查詢) from Table_1;
練習
找出包含 productid = 12 的訂單 order
發現有百百種方法
-
join orders & orderdetails 兩張 table 後,找出 productid = 12
select * from orders o, orderdetails od where o.orderid = od.OrderID and productid = 12; -
查詢出 orderdetails 中 productid = 12 的結果後,再與 orders Table join 在一起
SELECT * FROM orders, (SELECT * FROM orderdetails where productid = 12) od_p where orders.orderid = od_p.orderid; -
(老師版本)子查詢放在 where
select * from orders o where o.OrderID in ( select o.OrderID from orderdetails od where od.orderid = o.orderid and od.productid=15 );
作業練習
使用 orderdetails 的資料,查出訂單明細與產品名稱
- 請在 SQL 中的 SELECT 放入子查詢,查詢產品名稱
原本 join 的方式
select OrderDetailID, ProductName from orderdetails od, products p
where od.ProductID = p.ProductID;
改成老師需求的方式
想法
-
把 orderdetails table 加上 一欄 Product Name → 用 orderdetails table
select * from orderdetails od; -
從 products table 撈出 productname 欄位
select productname from products p; -
products 中的 productid 要與 orderdetails 中的 productid 對齊
select productname from products p where p.productid = od.productid;這邊的 orderdetail 可以用外部 SQL 語法取的,也就是 od
-
把第三步完成的子查詢加入第一步的查詢中,只需顯示 orderdetailid & productname 兩個欄位即可
select od.OrderDetailID, (select ProductName from products p where od.ProductID = p.ProductID) from orderdetails od;
單元 11 搜尋資料時用 exists 會更有效率
用來判斷子查詢有沒有查詢結果
回傳 True/False
select * from Table_1
where exists (子查詢)
練習
在 orders 表單中列出 productid = 12 的 orderid
-
在 in 章節中教了 in 的用法
-
order table
select * from orders o where o.orderid in (子查詢) -
子查詢要找出 orderdetails table 中 productid = 12 的 orderid
select od.orderid from orderdetails od where productid = 12; -
將步驟 2 的子查詢放入步驟 1
select * from orders o where o.orderid in (select od.orderid from orderdetails od where productid = 12);
-
exists 用法
在 orders table 中查找
select * from orders o where exists (子查詢)子查詢為 orderdetail 中 productid=12 的 orderid,其中 order.orderid = orderdetail.orderid
select od.orderid from orderdetails od where o.orderid = od.orderid and od.productid=12o 是利用外部的 SQL 語法
將 1 與 2 的子查詢結合
select * from orders o where exists (select od.orderid from orderdetails od where od.orderid = o.orderid and od.productid=12);
💡 建議常用 exists 關鍵字做兩張 Table 間的資料搜尋,會比較有效率
單元 12 新增資料
insert into Table(column1) values(1)
將資料塞入資料庫中
-
創建全新的資料:values
insert into TABLE(column1, column2) values (value1, value2); -
用子查詢的方式將資料塞入到指定的 table 與欄位
insert into TABLE_A(ta_column1, ta_column2) select new_id, tb_column1, tb_column2 from TABLE_B where 條件;ex 用 supplierid = 2 的 Name 與 Phone 建立新的 shipper:
insert into shippers(shipperid, shippername, phone) select 7, SupplierName, Phone from suppliers where SupplierID = 2;
作業
將名字塞入 employee table 中
insert into employees(employeeid, LastName, FirstName, BirthDate, Notes)
values (12, "Tsui", "Seraphine", "2000-01-01", "me");
單元 13 修改資料
update Table set column = where;
更新資料庫資料
update TABLE
set column1 = ""
where id = 3;
ex :
update shippers
set shipperName = "ABC"
where shipperid=5;
單元 14 刪除資料
delete from Table where
將資料庫中的資料刪除
delete from Table
where 條件;
ex 刪除 shipper table 中 shipperid = 4 的資料:
delete from shippers
where shipperid = 4;


























Comments
Post a Comment