如果沒有妥善的數據管理,企業的永續發展將會面臨困難。建立一個定義完善的系統對於管理內部和外部營運至關重要。對業務數據的深入洞察有助於理解整體工作流程並衡量績效。此外,使用資料庫可以節省時間,並能毫不費力地存取資訊。
什麼是資料庫?
一個 資料庫 是一個用於以安全方式儲存資訊的組織化系統。它提供分類功能,並允許建立資料表以將相似類型的項目歸類在同一個群組下。資料表提供了在多個列和欄中列出資訊的選項。因此,數據的品質和一致性得以提升。除了儲存和易於存取的功能外,資料庫在保護隱私和確保系統安全方面也扮演著重要角色。無論是臨時查詢還是編寫到應用程式中的流程一部分,檢索數據都是資料庫管理中最關鍵的方面之一。
一個 查詢 在關聯式 DMS 中是任何用於從資料表中檢索數據的指令。 SELECT 語句幾乎總是用於 結構化查詢語言 (SQL) 查詢中。有幾種方法可以從資料庫中檢索資訊。通常,開發人員更偏好命令列選項,因為它快速且有效。它允許無縫提交查詢。
在本指南中,我們將向您介紹 MySQL,並討論如何在 MySQL 中使用查詢。讓我們開始吧!
先決條件
要跟隨本教學,您需要具備以下條件:
-
最新版本的 Ubuntu 已安裝 在您的系統上。
-
系統使用者必須擁有 sudo 權限.
-
如果您在存取 sudo 帳戶時遇到困難,請考慮變更 MySQL root 密碼.
-
-
MySQL 已設定 在您的伺服器上。
步驟 1 — 建立並設定資料庫
在我們開始編寫第一個 SQL 查詢之前,我們需要建立一個資料庫並向其中新增資料表。之後,我們將使用範例數據填充這些資料表。使用資料庫將有助於您理解基本設定,並建立使用查詢的信心。
動手實踐是建立概念和理解資料庫重要性最有效的方法。在本指南中,我們將引導您了解資料庫的使用及其在解決現實世界問題中的重要性。讓我們來看一個情境,以了解資料庫如何幫助以結構化的方式組織記錄。
情境:我們將建立一個資料庫,記錄一群大學生出去度假慶祝生日。在去度假之前,他們計劃參加一場友誼游泳比賽。此外,群組中的每個朋友都計劃了一個活動待辦清單,以使他們的旅行更加刺激和愉快。
首先,以 root 使用者身份開啟 MySQL:
|
1 |
$ sudo mysql |
然後,透過執行以下指令來建立資料庫:
|
1 2 3 |
mysql> CREATE DATABASE `vacation`; Query OK, 1 row affected (0.52 sec) |
接下來,讓我們使用以下指令來使用我們的資料庫:
|
1 |
mysql> USE vacation; |
之後,我們將在資料庫中建立資料表。將第一個資料表命名為 celebration。我們的資料表將包含我們朋友姓名的欄位 (name)、他們贏得的錦標賽 (wins) 以及一個用於記錄他們 個人最佳 時間的 (time):
|
1 2 3 4 5 6 7 |
mysql> CREATE TABLE celebration ( -> name varchar(50), -> wins real, -> time real -> ); Query OK, 0 rows affected (2.03 sec) |
然後,我們將使用數據填充我們的資料表:
|
1 2 3 4 5 6 7 8 9 |
mysql> INSERT INTO celebration (name, wins, time) VALUES('Austin', '4', '15.5'), ('Ivan','7','9'), ('Aisha','10','5'), ('Zane','13','7.5'); Query OK, 4 rows affected (0.29 sec) Records: 4 Duplicates: 0 Warnings: 0 |
然後,在我們的資料庫中建立另一個資料表,用來儲存他們最喜愛的生日活動資訊。我們將建立一個名為 vacation ,並包含以下欄位:
|
列表 |
詳細資訊 |
|
name: |
儲存每位朋友的姓名。 |
|
birthdate: |
記錄每個人的出生日期。 |
|
activity: |
記錄他們最喜愛的活動。 |
|
Destination: |
儲存每個人最喜愛的目的地資訊。 |
|
meal: |
記錄個人最喜愛的餐點。 |
|
1 2 3 4 5 6 7 8 |
mysql> CREATE TABLE vacation ( name varchar(50), birthdate date, activity varchar(50), destination varchar(50), meal varchar(50) ); Query OK, 0 rows affected (0.09 sec) |
將資料填入資料表中:
|
1 2 3 4 5 6 7 8 9 10 |
mysql> CREATE TABLE vacation ( name varchar(50), birthdate date, activity varchar(50), destination varchar(50), meal varchar(50) ); Query OK, 0 rows affected (0.09 sec) Records: 4 Duplicates: 0 Warnings: 0 |
您現在已完成資料庫的設定。
步驟 2 — 開始使用 SELECT 語句
SQL 中的查詢通常以 SELECT 開始。它在查詢中用於指定應隨結果傳回資料表中的哪些欄位。查詢也必須始終包含 FROM,用於指定該語句將查詢的資料表。
查詢遵循以下語法:
|
1 |
mysql> SELECT column_to_select FROM table_to_select WHERE certain_conditions_apply; |
我們將使用查詢語法來傳回 meal 欄位,來自 vacation 資料表:
|
1 |
mysql> SELECT meal FROM vacation; |
我們的輸出將如下所示:
|
1 2 3 4 5 6 7 8 9 10 |
+-------+ | meal | +-------+ | Steak | | Sushi | | Fries | | Tofu | +-------+ 4 rows in set (0.00 sec) |
您也可以使用逗號來分隔並選取多個欄位:
|
1 |
mysql> SELECT name, destination FROM vacation; |
輸出:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+-------------+ | name | destination | +--------+-------------+ | Austin | Maldives | | Ivan | Mauritius | | Aisha | Colorado | | Zane | Bora Bora | +--------+-------------+ 4 rows in set (0.00 sec) |
您也可以使用 asterisk (*) 來代表資料表中的所有欄位:
|
1 |
mysql> SELECT * FROM celebration; |
輸出:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------+------+ | name | wins | time | +--------+------+------+ | Austin | 4 | 15.5 | | Ivan | 7 | 9 | | Aisha | 10 | 5 | | Zane | 13 | 7.5 | +--------+------+------+ 4 rows in set (0.00 sec) |
如果您想篩選符合特定條件的記錄,可以使用 WHERE。不符合指定條件的資料列將從結果中排除。 WHERE 子句使用以下語法:
|
1 |
mysql> . . . WHERE column_name comparison_operator value |
這是一個比較運算子,定義了應如何將指定的欄位與值進行比較。常見的 SQL 比較運算子包括:
|
運算子 |
用途 |
|
= |
等於 |
|
!= |
不等於 |
|
< |
小於 |
|
> |
大於 |
|
<= |
小於或等於 |
|
>= |
大於或等於 |
|
BETWEEN |
測試值是否在給定的範圍內。 |
|
IN |
測試某資料列的值是否包含在一組指定的值中。 |
|
EXISTS |
測試資料列是否存在 |
|
LIKE |
測試值是否符合指定的字串 |
|
IS NULL |
測試空值 |
|
IS NOT NULL |
測試非空值的所有值 |
如果您想找出 Aisha 最喜愛的目的地,可以使用以下查詢:
|
1 |
mysql> SELECT destination FROM vacation WHERE name ='Aisha'; |
該查詢接著將返回:
|
1 2 3 4 5 6 7 |
+-------------+ | destination | +-------------+ | Colorado | +-------------+ 1 row in set (0.03 sec) |
SQL 支援萬用字元的使用,這在以下子句中特別有用: WHERE 子句。百分比符號( %)表示零個或多個未知字元,而底線( _)則表示單個未知字元。如果您想在資料表中尋找特定條目,但不確定該條目的具體內容,這些字元會非常有用。
例如,如果您忘記了朋友最喜歡的目的地,只知道它開頭的字母,例如 “m”。您可以使用以下查詢來找到該目的地的名稱:
|
1 |
mysql> SELECT destination FROM vacation WHERE destination LIKE 'm%'; |
該查詢將返回:
|
1 2 3 4 5 6 7 8 |
+-------------+ | destination | +-------------+ | Maldives | | Mauritius | +-------------+ 2 rows in set (0.04 sec) |
在使用資料庫時,您可能會遇到名稱相對較長或難以閱讀的資料欄或資料表。在這些情況下,您可以使用 AS 關鍵字來建立別名。使用 AS 建立的別名僅在建立它們的查詢執行期間有效:
|
1 2 3 4 5 6 7 8 9 10 11 |
mysql> SELECT name AS E, destination as D, activity as A FROM vacation; +--------+-----------+-------------------+ | E | D | A | +--------+-----------+-------------------+ | Austin | Maldives | skiing | | Ivan | Mauritius | paragliding | | Aisha | Colorado | mountain climbing | | Zane | Bora Bora | fishing | +--------+-----------+-------------------+ 4 rows in set (0.00 sec) |
步驟 3 — 聚合函數介紹
處理資料時,您並不總是想看到資料本身。您可能更想獲得有關該資料的資訊。透過發送 SELECT 查詢,您可以使用 SQL 語法對資料進行解讀或計算。這些被稱為聚合函數。
其中 COUNT 函數會計算並返回符合特定條件組的行數。例如,如果您想知道有多少朋友更喜歡去 Maldives,您可以使用以下查詢:
|
1 |
mysql> SELECT COUNT(destination) FROM vacation WHERE destination = 'Maldives'; |
將返回以下結果:
|
1 2 3 4 5 6 7 |
+--------------------+ | COUNT(destination) | +--------------------+ | 1 | +--------------------+ 1 row in set (0.06 sec) |
MIN 用於尋找指定資料欄中的最小值:
|
1 |
mysql> SELECT MIN(wins) FROM celebration; |
該查詢將輸出:
|
1 2 3 4 5 6 7 |
+-----------+ | MIN(wins) | +-----------+ | 4 | +-----------+ 1 row in set (0.02 sec) |
MAX 用於尋找指定資料欄中的最大數值:
|
1 |
mysql> SELECT MAX(wins) FROM celebration; |
預期輸出為:
|
1 2 3 4 5 6 7 |
+-----------+ | MAX(wins) | +-----------+ | 13 | +-----------+ 1 row in set (0.03 sec) |
Both the MIN 和 MAX 函數都可以用於數值和字母數據。當應用於字串值資料欄時, MIN 函數會返回按字母順序排列的第一個值。
The MIN 函數會返回按字母順序排列的第一個值:
|
1 |
mysql> SELECT MIN(name) FROM celebration; |
以下是輸出結果:
|
1 2 3 4 5 6 7 |
+-----------+ | MIN(name) | +-----------+ | Aisha | +-----------+ 1 row in set (0.00 sec) |
The MAX 函數會返回按字母順序排列的最後一個值:
|
1 |
mysql> SELECT MAX(name) FROM celebration; |
輸出結果如下:
|
1 2 3 4 5 6 7 |
+-----------+ | MAX(name) | +-----------+ | Zane | +-----------+ 1 列 在 集合 (0.00 秒) |
步驟 4 — 操作查詢輸出
另一個常用的子句是 GROUP BY 子句。它用於對某一欄位執行聚合函數,但同時關聯到另一欄位中的匹配值:
|
1 |
mysql> SELECT COUNT(name), activity FROM vacation GROUP BY activity; |
輸出結果將為:
|
1 2 3 4 5 6 7 8 9 10 |
+-------------+-------------------+ | COUNT(name) | activity | +-------------+-------------------+ | 1 | skiing | | 1 | paragliding | | 1 | mountain climbing | | 1 | fishing | +-------------+-------------------+ 4 列 在 集合 (0.04 秒) |
若要對查詢結果進行排序,請使用 ORDER BY 子句。數值預設按升序排序,而文字值則按字母順序排序。下方的查詢列出了 name 和 birthdate 欄位,但會根據 birthdate:
|
1 |
mysql> SELECT name, birthdate FROM vacation ORDER BY birthdate; |
輸出結果如下:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------------+ | name | birthdate | +--------+------------+ | Zane | 1996-01-01 | | Aisha | 1999-07-24 | | Austin | 2002-01-07 | | Ivan | 2010-12-18 | +--------+------------+ 4 列 在 集合 (0.04 秒) |
輸出結果為升序,若要按降序排序,請在查詢末尾加上單字 DESC:
|
1 |
mysql> SELECT name, birthdate FROM vacation ORDER BY birthdate DESC; |
請看輸出結果:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------------+ | name | birthdate | +--------+------------+ | Ivan | 2010-12-18 | | Austin | 2002-01-07 | | Aisha | 1999-07-24 | | Zane | 1996-01-01 | +--------+------------+ 4 列 在 集合 (0.00 秒) |
The HAVING 子句被加入到 SQL 中,以提供與 WHERE 子句類似的功能,同時也與聚合函數相容。這兩個子句之間的區別在於 WHERE 用於引用單一記錄,而 HAVING 則用於引用群組記錄。因此,只要使用 HAVING 子句,就必須存在 GROUP BY 子句:
|
1 |
mysql> SELECT COUNT(name), activity FROM vacation GROUP BY activity HAVING COUNT(name) >= 1; |
查詢將輸出:
|
1 2 3 4 5 6 7 8 |
+-------------+-------------------+ | COUNT(name) | activity | +-------------+-------------------+ | 1 | skiing | | 1 | paragliding | | 1 | mountain climbing | | 1 | fishing | +-------------+-------------------+ |
The COUNT 在所有項目中皆為 1,因為沒有兩個朋友喜歡相同的活動。
步驟 5 — 查詢多個資料表
The JOIN 子句可用於查詢結果中,以合併來自兩個或多個資料表的資料列。它透過在資料表之間定位相關欄位並適當地對輸出進行排序來實現此目的。
SELECT 包含 JOIN 子句的陳述式遵循以下語法:
|
1 2 3 |
mysql> SELECT table1.column1, table2.column2 mysql> FROM table1 mysql> JOIN table2 ON table1.related_column=table2.related_column; |
如果您想為每個朋友購買獎盃,以表彰他們在 wins (於 swimming 期間)且適逢他們的 birthdays ,您可以建立一個查詢來連接這兩個資料表,以協助您透過單個查詢找到所需的所有資訊:
|
1 2 3 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate FROM celebration JOIN vacation ON celebration.name=vacation.name; |
輸出結果將為:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------+------------+ | name | wins | birthdate | +--------+------+------------+ | Austin | 4 | 2002-01-07 | | Ivan | 7 | 2010-12-18 | | Aisha | 10 | 1999-07-24 | | Zane | 13 | 1996-01-01 | +--------+------+------------+ 4 rows in set (0.00 sec) |
這是一個內 JOIN 子句。這是因為它會選取在兩個資料表中具有相符值的所有記錄,並將它們列印到結果集中。不符合查詢的記錄則不包含在內。我們可以在資料表中加入一個與任何項目都不對應的新列:
|
1 2 3 4 |
mysql> INSERT INTO celebration(name,wins,time) VALUES('Ella', '1', '120'); Query OK, 1 row affected (0.01 sec) |
|
1 2 3 4 |
mysql> INSERT INTO celebration(name,wins,time) VALUES('Ella', '1', '120'); Query OK, 1 row affected (0.01 sec) |
然後,重新執行 SELECT 陳述式,並加上 JOIN 子句:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate -> FROM celebration -> JOIN vacation ON celebration.name=vacation.name; +--------+------+------------+ | name | wins | birthdate | +--------+------+------------+ | Austin | 4 | 2002-01-07 | | Ivan | 7 | 2010-12-18 | | Aisha | 10 | 1999-07-24 | | Zane | 13 | 1996-01-01 | +--------+------+------------+ 4 rows in set (0.00 sec) |
因為 celebration 資料表沒有 Peter 的條目,而 vacation 資料表沒有 Ella 的條目,所以這些記錄不存在。
我們可以使用外 JOIN 子句來傳回其中一個資料表的所有記錄。這可以是 LEFT JOIN 或 RIGHT JOIN。 LEFT JOIN 會傳回左側資料表的所有記錄,以及右側資料表中相符的記錄。在外連接的上下文中,左側資料表是指由 FROM 子句所參照的資料表,而右側資料表則是在 JOIN 語句之後參照的任何資料表。
再次執行查詢,但使用 LEFT JOIN 子句:
|
1 2 3 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate FROM celebration LEFT JOIN vacation ON celebration.name=vacation.name; |
該命令將傳回左側資料表( celebration)的所有記錄,即使它在右側資料表中沒有對應的記錄。當右側資料表中沒有相符的記錄時,它會傳回為 NULL:
|
1 2 3 4 5 6 7 8 9 10 11 |
+--------+------+------------+ | name | wins | birthdate | +--------+------+------------+ | Austin | 4 | 2002-01-07 | | Ivan | 7 | 2010-12-18 | | Aisha | 10 | 1999-07-24 | | Zane | 13 | 1996-01-01 | | Ella | 1 | NULL | +--------+------+------------+ 5 rows in set (0.00 sec) |
現在這是 RIGHT JOIN 子句:
|
1 2 3 |
mysql> SELECT celebration.name, celebration.wins, vacation.birthdate FROM celebration RIGHT JOIN vacation ON celebration.name=vacation.name; |
右側資料表 (vacation) 的所有值都將被傳回。因為 Peter 的 birthdate 記錄在右側資料表中,而不在左側資料表的 name 和 wins 欄位中,因此這些欄位在這些列中將傳回 NULL 值:
|
1 2 3 4 5 6 7 8 9 10 11 |
+--------+------+------------+ | name | wins | birthdate | +--------+------+------------+ | Austin | 4 | 2002-01-07 | | Ivan | 7 | 2010-12-18 | | Aisha | 10 | 1999-07-24 | | Zane | 13 | 1996-01-01 | | NULL | NULL | 1991-05-03 | +--------+------+------------+ 5 行 在 集合 (0.01 秒) |
您可以使用 UNION 子句,而不是 JOIN 來查詢多個資料表中的記錄。 UNION 運算子與 JOIN 子句的不同之處在於,它將兩個 SELECT 陳述式的結果合併到單一資料欄中,而不是使用單一 SELECT 陳述式將多個資料表的結果列印為不重複的資料欄。
您可以執行此查詢來進行說明:
|
1 |
mysql> SELECT name FROM celebration UNION SELECT name FROM vacation; |
此查詢會移除重複的項目。這是 UNION 運算子的預設行為:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
+--------+ | name | +--------+ | Austin | | Ivan | | Aisha | | Zane | | Ella | | Peter | +--------+ 6 行 在 集合 (0.00 秒) |
若要傳回所有項目(包括重複項目),請使用 UNION ALL 運算子:
|
1 |
mysql> SELECT name FROM celebration UNION ALL SELECT name FROM vacation; |
輸出:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
+--------+ | name | +--------+ | Austin | | Ivan | | Aisha | | Zane | | Ella | | Austin | | Ivan | | Aisha | | Zane | | Peter | +--------+ 10 行 在 集合 (0.00 秒) |
子查詢是查詢多個資料表的另一種方法。子查詢是巢狀於另一個查詢內部的查詢(也稱為內部查詢或巢狀查詢)。當您想要將某個查詢的結果與另一個獨立聚合函數的結果進行比較時,子查詢非常有用。
我們將以尋找哪位朋友贏得比 Ella 更多的游泳比賽為例。您不需要先查詢 Ella 贏了多少場比賽,然後再執行另一個查詢來查看誰贏得比她更多,而是可以使用單一查詢來計算這兩者:
|
1 2 3 4 |
mysql> SELECT name, wins FROM celebration -> WHERE wins > ( -> SELECT wins FROM celebration WHERE name = 'Ella' -> ); |
此查詢將傳回:
|
1 2 3 4 5 6 7 8 9 10 |
+--------+------+ | name | wins | +--------+------+ | Austin | 4 | | Ivan | 7 | | Aisha | 10 | | Zane | 13 | +--------+------+ 4 行 在 集合 (0.06 秒) |
如果您想帶您的朋友去度過一個驚喜假期,您可以使用查詢來查看誰贏得最多,並傳回他們的目的地:
|
1 2 3 4 |
mysql> SELECT name, destination, activity, meal -> FROM vacation -> WHERE name = ( SELECT name FROM celebration -> WHERE wins = (SELECT MAX(wins) FROM celebration)); |
此查詢將傳回:
|
1 2 3 4 5 6 7 |
+------+-------------+----------+------+ | name | destination | activity | meal | +------+-------------+----------+------+ | Zane | Bora Bora | fishing | Tofu | +------+-------------+----------+------+ 1 行 在 集合 (0.00 秒) |
此陳述式包含一個巢狀於子查詢內部的子查詢。
結論
查詢生成是資料庫管理中最常見的工作之一。有幾種資料庫管理工具,例如 phpMyAdmin 和 pgAdmin,您可以使用它們來處理查詢並將其結果視覺化。然而,命令列中的 SELECT 陳述式因其易用性和出色的控制能力而成為最受青睞的選擇。
此外,還有許多關於資料庫的教學課程,您可以從我們的 部落格中探索:
- SQLite vs MySQL vs. PostgreSQL:關聯式資料庫管理系統比較
- 修復 MySQL 中損壞資料表的快速解決方案:教學
- 如何在 Centos 7 上安裝 MySQL
- MySQL 使用者 — 建立與授予權限
- 在 Ubuntu 上的 MySQL 中設定複製
祝您電腦使用愉快!
留言
目前尚無留言。成為第一個留言的人吧。