SQL與MySQL簡介


SQL與MySQL簡介

數據庫基礎

從SQL的角度來看,數據庫就是一個以某種有組織的方式存儲的數據集合。我們可以采用數據庫對數據進行有效的存儲與管理,並運用數據庫進行合理的處理與分析,使其轉化為有價值的數據信息。

理解數據庫的一種簡單辦法是將其想象為一個存放數據的文件櫃,
往文件櫃里存放數據資料時,先在文件櫃中創建文件,然后將相關的數據資料放入特定的文件中,這種存儲某種特定類型數據的結構化的文件就稱為表。每個表都有唯一的表名(在同一數據庫中不能有兩個相同的表名)。表由列組成,每一列存儲着某種特定的信息,並且具有相應的數據類型。表中的數據是按行存儲的,所保存的每個記錄存儲在自己的行內,並且應盡量保證每一行都有一列(或幾列)能夠唯一標識該行的主鍵。表中的任何列都可以作為主鍵,只要它滿足以下條件:任意兩行主鍵值不同、主鍵列不允許NULL值,且習慣上不更新或重用主鍵值。

什么是SQL

SQL(發音為字母S-Q-L或sequel)的全稱為“Structured Query Language”
(結構化查詢語言),是一種專門用來與數據庫溝通的語言,用以查詢關系數據庫表的內容,以及插入、更新和刪除數據。SQL簡潔易學,功能強大,靈活使用其語言元素,可以進行非常復雜和高級的數據庫操作。

SQL不是某個特定數據庫供應商專有的語言,幾乎所有主要的DBMS(數據庫管理系統)都支持SQL,因此掌握該語言使你幾乎能與所有數據庫打交道。標准SQL由ANSI標准委員會管理,從而稱為ANSI
SQL。所有主要的DBMS即使有自己的擴展(提供執行特定操作的額外功能或簡化方法),也都支持ANSI
SQL。本教程主要使用標准SQL,提供的SQL示例代碼在MySQL 5.7.19環境下測試通過,然而本教程所探討的概念也適用於其他SQL環境。

下載與安裝MySQL

SQL不是一個應用,而是一種語言。因此,為了學習SQL,我們還需要一個支持SQL語句執行的應用程序。實際上,數據的所有存儲、檢索、管理和處理都是由數據庫軟件——DBMS(數據庫管理系統)完成的。較為流行的DBMS包括MySQL、
Oracle、 Microsoft SQL Sever、 PostgreSQL等,以下主要介紹MySQL。

MySQL是一個開源的關系型數據庫管理系統,由瑞典MySQL AB公司開發,目前為 Oracle
旗下產品,是世界上最受歡迎的數據庫管理系統之一。MySQL官網下載地址為: [ https://dev.mysql.com/downloads/mysql/

](https://dev.mysql.com/downloads/mysql/) 。在Windows環境下以MSI方式安裝步驟如下:

  1. 在官網 [ https://dev.mysql.com/downloads/windows/installer/5.7.html

](https://dev.mysql.com/downloads/windows/installer/5.7.html)
下載最新5.7社區版的安裝包之后,雙擊MSI安裝文件,出現安裝協議界面,同意協議,並單擊【next】;

  1. 選擇安裝類型。默認安裝【developer Default】(包含有MySQL Workbench),此外,可以根據需要選擇 【server
    only】(僅安裝服務器)、 【client only】(僅安裝客戶端)、 【full】 (安裝全部功能) 或者 【custom】
    (自定義安裝),右側的【Setup Type Description】給出了每一種安裝類型所包含的安裝項目。

  2. Check Requirements。如果提示電腦上缺少相關組件(如python),可以根據提示下載安裝,也可以選擇直接單擊【next】進入下一步;

  3. 選擇【Execute】開始正式安裝,並且可以看到安裝進度;

  4. 安裝完成后根據提示點擊【next】按鈕進入如下產品配置面板,選擇【next】;

  5. 根據需要選擇服務器類型(默認為 【Developer Machine】),TCP/IP默認端口為3306;

  6. 進入【賬戶和角色】面板。根據提示設置root賬戶密碼,並可根據需要添加用戶;

  7. 之后可根據安裝向導保持默認選項,選擇【next】及【execute】直到出現以下界面表示配置完成,並根據需要選擇是否啟動MySQL
    Workbench及MySQL Shell。

使用MySQL

有兩種方式使用MySQL。在安裝MySQL時會自帶一個名為mysql命令行實用程序,這是一個純文本工具,可以用來執行任何SQL語句。另外,MySQL
官方發布了一個名為MySQL
Workbench的可視化管理工具,用戶可以在安裝MySQL時一起選擇安裝,也可以獨立下載安裝。較為流行的MySQL數據庫可視化管理工具包括MySQL
Workbench、 Navicat、 phpMyAdmin、Sequel Pro等。在Windows平台學習SQL時,推薦使用MySQL
Workbench。

(1)mysql命令行實用程序

  • 有兩種方式使用mysql命令行實用程序。第一種方式是從開始菜單欄中打開MySQL 5.7 Command Line Client,輸入密碼,出現如下界面表示數據庫連接成功:
    • 第二種方式:如果已經將MySQL Sever安裝目錄下的bin子目錄加入到了windows的環境變量中,可以直接在命令行中輸入mysql -u root -p 命令,回車后輸入密碼即可連接成功。如下圖所示:
    • 數據庫連接成功后,在mysql>提示下輸入USE database 打開數據庫,例如USE world就是打開world數據庫。
    • 在mysql>提示下輸入SQL語句,每條語句須以分號(;)結束。結果將顯示在屏幕上。
    • 輸入\h可以顯示可能用到的命令列表,輸入\s可以顯示狀態信息(如MySQL版本信息)。
    • 輸入\q或quit可以退出程序。

(2)可視化管理工具 MySQL Workbench

盡管我們可以在命令提示符下通過一行行的輸入或者通過重定向文件來執行mysql語句,但該方式效率較低, 且由於沒有執行前的語法自動檢查,
輸入失誤造成的一些錯誤的可能性會大大增加。使用MySQL Workbench 可以通過可視化的方式直接管理數據庫中的內容, 並且 MySQL
Workbench 的 SQL 腳本編輯器支持語法高亮以及輸入時的語法檢查,方便我們學習SQL。可通過以下操作使用MySQL Workbench:

* 運行MySQL Workbench。界面左下角列出了可用的MySQL數據庫連接,可直接點擊打開,輸入密碼便可連接。如果沒有在此列出,可選擇【MySQL Connections】右側的加號按鈕,創建新的連接。   

* 登陸成功后的Workbench界面概覽如下圖所示:   


其中,區域1顯示的是數據庫服務器中已經創建的數據庫列表。區域2是關於數據庫的操作列表。區域3是sql的編輯器和執行環境,區域4是執行結果的列表。

* 輸入SQL語句后,點擊Execute(帶有閃電圖片) 或使用快捷鍵【ctrl+enter】運行SQL,將結果顯示在下面。如下圖所示:   

導入樣例表

完成前面的安裝與設定工作后,MySQL中已經有一個內建的范例數據庫world。但這個數據庫比較簡單,為了更好地練習SQL語句,我們還需要做最后一項准備工作:導入樣例表。后續教程將會基於此樣例表編寫各式SQL語句。

(1)樣例表描述
本教程采用著名暢銷書Sams Teach Yourself SQL in 10 Minutes
一書中所提供的樣例表。樣例表描述的是一個隨身物品推銷商使用的訂單錄入系統,下圖顯示了5張表之間的關系:

其中,Customers表存儲所有顧客信息;Vendors表存儲銷售產品的供應商,每個供應商在這個表中都有一個記錄,包含了供應商名字、地址、所在城市等數據元素,其中使用vend_id作為其主鍵;Products表包含產品目錄,每行一個產品,並且借助vend_id(供應商的唯一ID)與供應商相關聯;Orders表存儲顧客訂單,每個訂單都有唯一編號(order_num列),且根據cust_id列關聯到相應的顧客;OrderItems表則存儲每個訂單中的實際物品,每個訂單的每個物品一行。對於Orders表的每一行,在OrderItems表中有一行或多行與之對應。每個訂單物品由訂單號加訂單物品(第一個物品、第二個物品等)唯一標識。訂單物品用order_num列與其相應的訂單相關聯。此外,每個訂單物品還包含該物品的產品ID(把物品關聯到Products表)。上圖中表之間的連線便說明了表之間的關系。

(2)導入樣例表

從 [ http://www.forta.com/books/0672336073/

](http://www.forta.com/books/0672336073/) 下載適用於MySQL的SQL腳本,含有兩個文件:

  • create.txt包含創建5個數據庫表(包括定義所有主鍵和外鍵約束)的SQL語句。
  • populate.txt包含用來填充這些表的SQL INSERT語句。

導入步驟如下:

  • 根據上述教程,運行MySQL Workbench,並連接到MySQL。新建一個數據庫,點擊【Create a New Schema】按鈕,出現如下對話框。輸入新建數據庫的名稱,選擇【apply】。
    • 在彈出的確認窗口中選擇【Apply】及【Finish】。然后在SCHEMAS一欄中雙擊創建成功的tjsql,表示選中該數據庫,可以看到tjsql一欄變為黑體。
    • 將create.txt中的內容復制粘貼到SQL窗口中,並選擇執行,用以創建5個數據庫表;
      同樣,將populate.txt中的內容復制粘貼到SQL窗口中並執行,用以填充5個數據庫表。
    • 使用SELECT * FROM Customers; 語句測試結果如下圖表示導入成功。

查看數據庫和表

(1)查看數據庫

在MySQL中可以建立許多數據庫,當不知道可以使用哪些數據庫時,可用MySQL的SHOW命令顯示當前可用的數據庫列表:

    SHOW DATABASES;
    
    顯示當前服務器的所有數據庫

在MySQL Workbench中輸出結果為:

包含在這個列表中的可能是MySQL內部使用的數據庫(如information_schema)。當然,你自己的數據庫列表可能看上去與這里的不一樣。

(2)選擇數據庫
在執行任何數據庫操作前,都需要選擇一個數據庫,才能讀取其中的數據。方法是使用USE關鍵字:

    USE tjsql;
    
    選擇使用tjsql數據庫
[/code]

USE 語句並不返回任何結果。如果是在MySQL
Workbench中運行該語句,可以在SCHEMAS一欄看到被選中的數據庫名稱變為黑體(與雙擊該數據庫名稱等效);如果是在mysql
命令行實用程序中執行該語句,則會顯示輸出“Database changed” 表示數據庫選擇成功。

**(3)查看數據表**  
進入到某個數據庫后,我們可以使用 SHOW TABLES;來顯示該數據庫有多少個數據表:

```code
    SHOW TABLES;
    
    顯示當前數據庫下所有的表
[/code]

例如,選擇tjsql數據庫后運行該語句的輸出為:

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010211942314.png)

同樣,SHOW 也可以用來顯示表列:

```code
    SHOW COLUMNS FROM customers;
    
    顯示customers表每個字段的數據類型、是否允許 NULL 、鍵信息、默認值以及其他信息
[/code]

輸出為:  
![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010212228279.png)

此外,MySQL還支持用 DESCRIBE 作為 SHOW COLUMNS FROM 的一種快捷方式。例如,DESCRIBE customers;
與SHOW COLUMNS FROM customers; 有着相同的輸出,兩者完成同樣的功能。

MySQL所支持的其他 SHOW 語句還有:  
- SHOW STATUS :用於顯示廣泛的服務器狀態信息;   
- SHOW CREATE DATABASE和SHOW CREATE TABLE :用來顯示創建特定數據庫或表的MySQL語句;   
- SHOW GRANTS :用來顯示授予用戶的安全權限;   
- SHOW ERRORS 和 SHOW WARNINGS :用來顯示服務器錯誤或警告消息。 

##  SELECT基礎查詢

在第一部分,我們介紹了數據庫和SQL的概念,以及MySQL安裝和使用的一些相關知識,並導入了准備好的樣例表,完成了SQL環境的基本搭建。在第二部分,我們將會介紹SELECT語句的基礎知識,並用它來進行一些基本的SQL查詢。

###  檢索數據

在數據分析過程中,SELECT語句是最經常使用的SQL語句。它的用途是從一個或多個表中檢索數據。為此,至少需要給出兩條信息——想選擇什么,以及從什么地方選擇。  
**(1)檢索單個列**

最基礎的SELECT 語句如下所示:

```code
    SELECT prod_name
    FROM Products;
    
    從 Products 表中檢索一個名為prod_name 的列

在上述語句中,所需的列名在 SELECT 關鍵字之后給出, FROM關鍵字指出從其中檢索數據的表名。返回的數據沒有過濾,也沒有經過排序。輸出如下所示:

(2)檢索多個列
從一個表中檢索多個列,只需在 SELECT 關鍵字后給出多個列名,列名之間以逗號分隔:

    SELECT prod_id, prod_name, prod_price
    FROM Products;
    
    從 Products 表中檢索prod_id, prod_name, prod_price三個列

(3)檢索所有列
使用星號(*)通配符可以檢索所有列而不必逐個列出所有的列名:

    SELECT *
    FROM Products;
    
    返回 Products 表中所有列
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-2017101021275733.png)

注:使用通配符的好處是比較方便,且能檢索出名字未知的列。但通常會降低檢索和應用程序的性能,除非確實需要表中的每個列,否則最好別使用*通配符。

**(4)檢索不同的行**  
如前所述,SELECT語句會返回所有匹配的行。如果不希望相同的記錄重復出現,可使用 DISTINCT 關鍵字:

```code
    SELECT DISTINCT vend_id
    FROM Products;
    
    返回 Products 表中不同(唯一)的vend_id 行
[/code]

該語句只返回三行不重復值的vend_id。如下所示:  
![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010212913672.png)

與之相對的,如果不指定DISTINCT關鍵字,只輸入SELECT vend_id FROM Products;則會返回9行(分別對應Products
表中9種產品):

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010212928972.png)

注:不能部分使用 DISTINCT關鍵字。DISTINCT作用於所有的列,不僅僅是跟在其后的那一列。例如,指定SELECT DISTINCT
vend_id, prod_price,除非指定的兩列完全相同,否則所有的行都會被檢索出來。

**(5)限制結果**

若只需要返回第一行或前幾行,可使用 LIMIT 子句:

```code
    SELECT prod_name
    FROM Products
    LIMIT 5;
    
    只返回 Products 表中前5行記錄
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010212958642.png)

除了使用LIMIT關鍵字指定返回的行數之外,還可以使用OFFSET 關鍵字指定從哪一行開始檢索:

```code
    SELECT prod_name
    FROM Products
    LIMIT 5 OFFSET 5;
    
    返回 Products 表中從第5行起的5行數據
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213033664.png)

可以發現,在這個例子中只返回了4行,這是因為在Products表中只有9種產品,而第一個被檢索的產品稱為第0行,最后一個被檢索的產品是第8行,所以最終只返回了4行數據。

注:MySQL還支持簡化版的“LIMIT 4O FFSET 3”,即“LIMIT 3,4”,表示從行3開始取4行。

###  排序檢索數據

這個部分會簡單介紹如何使用 SELECT 語句的 ORDER BY 子句對檢索出來的數據在一個或多個列上進行排序。

**(1)按單個列排序**  
使用ORDER BY子句進行排序方法如下:

```code
    SELECT prod_name
    FROM Products
    ORDER BY prod_name;
    
    檢索 Products 表的prod_name列,並按prod_name列字母順序排序
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-2017101021312661.png)

與之對比,若不指定順序,輸入“SELECT prod_name FROM Products”語句則輸出結果為:  
![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213138209.png)

如果不排序,數據一般以它在底層表中出現的順序顯示,這有可能是數據最初添加到表中的順序。但如果數據進行過更新或刪除,則這個順序將會受到DBMS重用回收存儲空間的方式的影響。因此,關系數據庫設計理論認為,如果不明確規定排序順序,則不應該假定檢索出的數據的順序有任何意義。

**(2)按多個列排序**

要按多個列排序,只需指定多個列名,列名之間用逗號分開即可:

```code
    SELECT prod_id, prod_price, prod_name
    FROM Products
    ORDER BY prod_price, prod_name;
    檢索Products 表中的3個列,先按價格排序,然后按名稱排序
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213200318.png)

注: ORDER BY子句允許選用非檢索的列作為排序依據。

**(3)按列位置排序**  
ORDER BY支持按相對列位置進行排序:

```code
    SELECT prod_id, prod_price, prod_name
    FROM Products
    ORDER BY 2, 3;
    先按SELECT清單中第二個列prod_price(價格)進行排序,然后按第三個列prod_name(名稱)排序
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213223433.png)

按列相對位置排序好處在於不用重新輸入列名,但需要特別注意每個列名的確切位置,以免在對SELECT清單進行更改時錯用列名排序。

**(4)指定排序方向**  
排序時,默認為升序排序(從A到Z),但可以指定DESC關鍵字降序排序(從Z到A):

```code
    SELECT prod_id, prod_price, prod_name
    FROM Products
    ORDER BY prod_price DESC, prod_name;
    
    對prod_price列降序排序,對prod_name列仍按升序排序。
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213250237.png)

從上述例子中可以看出,DESC關鍵字只作用於直接位於其前面的列名。如果想在多個列上進行降序排序,必須對每一列指定DESC關鍵字。

使用 ORDER BY 和 LIMIT 的組合,能夠找出一個列中最高或最低的值。下面的例子演示如何找出最昂貴物品的值:

```code
    SELECT prod_price
    FROM Products
    ORDER BY prod_price DESC
    LIMIT 1;
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213330882.png)

注:需要注意ORDER BY子句的位置。在給出 ORDER BY 子句時,應該保證它位於 FROM 子句之后。如果使用 LIMIT關鍵字 ,則它須位於
ORDER BY之后。一般來說,ORDER BY 子句必須是SELECT 語句中的最后一條子句。

###  過濾數據

本節會介紹如何使用SELECT語句的WHERE子句指定搜索條件過濾返回的數據。

**(1)使用WHERE子句**

在 SELECT 語句中,WHERE子句在FROM子句之后給出,返回滿足指定搜索條件的數據:

```code
    SELECT prod_name, prod_price
    FROM Products
    WHERE prod_price = 3.49;
    
    從products表中檢索兩個列,但只返回prod_price值為3.49的行
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-2017101021342399.png)

除了上述例子的相等條件判斷,WHERE子句還支持以下條件操作符:  
![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213518619.png)

例如,使用<>操作符(或!=)進行不匹配檢查:

```code
    SELECT vend_id, prod_name
    FROM Products
    WHERE vend_id <> 'DLL01';
    
    從Products表中列出所有不是供應商DLL01制造的產品
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213548694.png)

再如,使用BETWEEN操作符可匹配處於某個范圍內的值。需要指定范圍的端點值:

```code
    SELECT prod_name, prod_price
    FROM Products
    WHERE prod_price BETWEEN 5.99 AND 9.49;
    
    檢索價格在5.99美元和9.49美元之間的所有產品(包括5.99美元和9.49美元)
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213613344.png)

此外,還有一個特殊的IS NULL子句,可用來檢查具有 NULL 值的列:

```code
    SELECT cust_name
    FROM CUSTOMERS
    WHERE cust_email IS NULL;
    
    返回沒有郵件地址為NULL的顧客。
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213637388.png)

**(2)組合WHERE子句**

SQL還允許使用AND或OR操作符組合出多個WHERE子句,例如使用AND操作符:

```code
    SELECT prod_id, prod_price, prod_name
    FROM Products
    WHERE vend_id = 'DLL01' AND prod_price <= 4;
    
    檢索由供應商DLL01制造且價格小於等於4美元的所有產品的名稱和價格(需同時滿足兩個條件)
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010213708908.png)

同理,可使用OR操作符檢索匹配任一條件的行:

```code
    SELECT prod_name, prod_price
    FROM Products
    WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
    
    檢索由供應商DLL01或供應商BRS01制造的所有產品的名稱和價格(只需滿足任一條件即可)
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010225953248.png)

**(3)求值順序**

WHERE子句允許包含任意數目的AND和OR操作符以進行復雜、高級的過濾。但需要注意求值順序:AND操作符優先級高於OR操作符,但可以使用圓括號明確地指定求值順序:

```code
    SELECT prod_name, prod_price
    FROM Products
    WHERE (vend_id = 'DLL01' OR vend_id = ‘BRS01’)
    AND prod_price <= 10;
    
    選擇由供應商DLL01或BRS01制造的,且價格在10美元及以下的所有產品
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010230024691.png)

**(4)IN操作符**

IN操作符用來指定條件范圍,范圍中的每個條件都可以進行匹配。條件之間用逗號分隔:

```code
    SELECT prod_name, prod_price
    FROM Products
    WHERE vend_id IN ( 'DLL01', 'BRS01' )
    ORDER BY prod_name;
    
    檢索由供應商DLL01和BRS01制造的所有產品
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010230048326.png)

注:IN操作符完成了與OR相同的功能,但與OR相比,IN操作符有如下優點:  
- 有多個條件時,IN操作符比一組OR操作符更清楚直觀且執行得更快;   
- 在與其他AND和OR操作符組合使用IN時,求值順序更容易管理;   
- IN操作符的最大優點是可以包含其他SELECT語句,能動態地建立WHERE子句。 

**(4)NOT操作符**

NOT操作符用來否定跟在它之后的條件:

```code
    SELECT vend_id,prod_name
    FROM Products
    WHERE NOT vend_id = 'DLL01'
    ORDER BY prod_name;
    
    用來檢索除了供應商DLL01之外制造的所有產品
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010230116261.png)

上面的例子也可以使用<>操作符來完成。但在更復雜的子句中,NOT是非常有用的。例如,在與IN操作符聯合使用時,NOT可以非常簡單地找出與條件列表不匹配的行:

```code
    SELECT vend_id,prod_name
    FROM Products
    WHERE vend_id NOT IN ( 'DLL01', 'BRS01' )
    ORDER BY prod_name;
    
    用來檢索除了供應商DLL01和BRS01之外制造的所有產品
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010230139533.png)

注:和多數其他 DBMS允許使用 NOT 對各種條件取反不同,MySQL支持使用 NOT 對 IN 、 BETWEEN 和EXISTS子句取反。

**(5)LIKE操作符**

使用LIKE操作符和通配符可以進行模糊搜索,以便對數據進行復雜過濾。最常使用的通配符是百分號( % ),它可以表示任何字符出現任意次數:

```code
    SELECT prod_id, prod_name
    FROM Products
    WHERE prod_name LIKE '%bean bag%';
    
    檢索產品名含有[bean bag]字段的所有產品
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010230204348.png)

另一個有用的通配符是下划線(_)。它的用途與%一樣,但只匹配單個字符,而不是多個或0個字符:

```code
    SELECT prod_id, prod_name
    FROM Products
    WHERE prod_name LIKE '_ inch teddy bear';
    
    檢索產品名含有[ inch teddy bear]字段的產品,且[ inch teddy bear]字段前有且只能有一個字符
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010230228239.png)

注:通配符搜索只能用於文本字段(串),非文本數據類型字段不能使用通配符搜索。

###  2.4 函數

這部分將會介紹什么是計算字段以及MySQL支持的部分數據處理函數。

**(1)計算字段**  
有時候從數據庫中直接檢索出來的數據並不是我們想要的,我們希望得到的是經過轉換、計算或格式化過的數據。例如,在物品訂單表中存儲的是物品的價格和數量,但我們需要的是每個物品的總價格(用價格乘以數量即可)。這時候計算字段就可以排上用場了。計算字段並不實際存在於數據庫表中,而是運行時在SELECT語句內創建的。

```code
    SELECT prod_id,
           quantity,
           item_price,
    quantity*item_price AS expanded_price
    FROM OrderItems
    WHERE order_num = 20008;
    
    求得訂單號20008中每個物品的數量、單價以及總價格(單價乘數量)

在該例中,quantity*item_price 表示對檢索出的數據進行算術計算, AS
expanded_price指示SQL創建了一個包含指定計算結果的名為expanded_price的計算字段。其中expanded_price叫做別名,用AS關鍵字賦予,客戶端應用可以像使用其他列一樣引用這個新計算列。

SQL支持+、-、*、/(加減乘除)四種基本算術操作符。此外,圓括號可用來區分優先順序。

除了算術運算,我們還經常使用拼接字段。例如,vendors 表的兩個列 vend_name 和
vend_country分別存儲了供應商的名字和位置信息,假如要生成一個供應商報表,需要按照 name(location)
這樣的格式列出供應商的信息,即把vend_name和 vend_country兩個列拼接起來。在MySQL中,可使用Concat() 函數來拼接兩個列:

    SELECT Concat(vend_name,’(’,vend_country,’)’)
     AS vend_title
    FROM Vendors
    ORDER BY vend_name;
    
    將vend_name和 vend_country兩個列拼接成 name(location) 的格式,並叫做別名vend_title

(2)數據處理函數

與大多數其他計算機語言一樣,SQL支持利用用函數來處理數據。上述用來拼接兩個列的Concat()就是函數的一個例子
。大多數SQL實現支持4種類型的函數:文本處理函數、日期和時間處理函數、數值處理函數以及返回DBMS正使用的特殊信息(如返回用戶登錄信息,檢查版本細節)的系統函數。一下簡要介紹前三種數據處理函數。

  • 文本處理函數 :用於處理文本串(如刪除或填充值,轉換值為大寫或小寫)的文本函數。例如將文本轉換為大寫的Upper() 函數:
    SELECT vend_name, UPPER(vend_name) AS vend_name_upcase
    FROM Vendors
    ORDER BY vend_name;
    
    將vend_name列轉換為大寫

下表列出了一些常用的文本處理函數。

上表中的SOUNDEX 需要做進一步的解釋。 SOUNDEX 是一個將任何文本串轉換為描述其語音表示的字母數字模式的算法。 SOUNDEX
考慮了類似的發音字符和音節,使得能對串進行發音比較而不是字母比較。

例如,Customers表中有一個顧客Kids Place,其聯系名為Michelle Green。但如果這是
錯誤的輸入,此聯系名實際上應該是Michael Green,如果使用SOUNDEX()函數進行搜索,它就有匹配所有發音類似於Michael
Green的聯系名:

    SELECT cust_name, cust_contact
    FROM Customers
    WHERE SOUNDEX(cust_contact) = SOUNDEX('Michael Green');
    
    匹配所有發音類似於Michael Green的聯系名

  • 日期和時間處理函數 :用於處理日期和時間值並從這些值中提取特定成分(例如,返回兩個日期之差,檢查日期有效性等)的日期和時間函數。目前為止,我們都是用比較數值和文本的 WHERE 子句過濾數據,但數據經常需要用日期進行過濾。

下表列出了一些常用的日期和時間處理函數。

需要注意MySQL使用的日期格式必須為yyyy-mm-
dd,例如2017年1月1日,應寫成2017-01-01。一般如果要對日期進行比較,需使用Date()函數:

    SELECT cust_id, order_num,order_date
    FROM Orders
    WHERE Date(order_date) BETWEEN '2012-01-01' AND '2012-01-31';
    
    匹配2012年1月份下的所有訂單

還有另外一種辦法是使用Year()和Month()函數:

    SELECT cust_id, order_num,order_date
    FROM Orders
    WHERE Year(order_date) = 2012 AND Month(order_date) = 1;
    
    匹配2012年1月份下的所有訂單

  • 數值處理函數 :用於在數值數據上進行算術操作(如返回絕對值,進行代數運算)的數值函數。這些函數主要用於代數、三角或幾何運算,因此沒有串或日期時間處理函數的使用那么頻繁。但在主要DBMS的函數中,數值函數是最一致最統一的函數,而文本處理函數、日期和時間處理函數在不同的DBMS中差別卻很大。以下是一些常用的數值處理函數:

(3)聚集函數

有時我們實際需要的是表中數據的匯總信息,而不是實際數據本身,比如確定表中行數、表列的最大值、最小值和平均值等。為此,MySQL給出了5個聚集函數:

  • AVG()函數 :返回所有列的平均值,也可以用來返回特定列或行的平均值。如:
    SELECT AVG(prod_price) AS avg_price
    FROM Products;
    
    返回Products表中所有產品的平均價格

  • COUNT()函數 :確定表中行的數目或符合特定條件的行的數目。COUNT()函數有兩種使用方式。第一種是使用COUNT(*)對表中行的數目進行計數,不管表列中包含的是空值(NULL)還是非空值:
    SELECT COUNT(*) AS num_cust
    FROM Customers;     
    
    返回Customers表中顧客的總數

另一種方式是使用COUNT(column)對特定列中具有值的行進行計數,忽略NULL值:

    SELECT COUNT(cust_email) AS num_cust
    FROM Customers;
    
    返回Customers表中具有電子郵件地址的顧客的總數

在此例子中,使用COUNT(cust_email)對cust_email列中有值的行進行計數,輸出結果為3表示5個顧客中只有3個顧客有電子郵件地址,忽略NULL值。

  • MAX()函數 :返回指定列中的最大值,且要求指定列名:
    SELECT MAX(prod_price) AS max_price
    FROM Products;
    
    返回Products表中最貴物品的價格

注:MAX()一般用來找出最大的數值或日期值,在用於文本數據時,如果數據按相應的列排序,則 MAX() 返回最后一行。

  • MIN()函數 :與MAX()函數相反,返回指定列的最小值。
  • SUM()函數 :返回指定列值的和(總計)。例如:
    SELECT SUM(item_price*quantity) AS total_price
    FROM OrderItems
    WHERE order_num = 20005;
    
    返回訂單中所有物品價錢之和

在使用以上聚集函數時,如果只想聚集不同值,可指定 DISTINCT 參數去重:

    SELECT AVG(DISTINCT prod_price) AS price_avg,
            MAX(DISTINCT prod_price) AS price_max
    FROM Products
    WHERE vend_id = 'DLL01';
    
    返回產品的平均價格及最高價格,但只考慮各個不同的價格

從本例中可以看出,使用了DISTINCT后,排除了多個具有相同的較低價格的物品之后,price_avg相對比較高。但是將DISTINCT用於MIN()和MAX()並不會改變一個列中的最小值和最大值。此外,DISTINCT不能用於COUNT(*)。
注:與DISTINCT參數相對的是ALL參數,但ALL參數不需要指定,因為這是默認的。

2.5 分組數據

本小節將會介紹如何使用GROUP BY 子句和 HAVING 子句分組數據。

(1)使用GROUP BY 子句創建分組

GROUP BY
子句能把數據分為多個邏輯組,並使用聚集函數對每個組進行聚集計算,以解決諸如返回每個供應商提供的產品數目、返回只提供單項產品的供應商所提供的產品或返回提供10個以上產品的供應商等問題。考察以下例子:

    SELECT vend_id, COUNT(*) AS num_prods
    FROM Products
    GROUP BY vend_id;       
    
    vend_id為產品供應商的ID,num_prods為計算字段(用COUNT(*)函數建立),GROUP BY 子句將根據vend_id進行數據分組

從輸出中可以看到,供應商BRS01有3個產品,供應商DLL01有4個,供應商FNG01有2個產品。使用GROUP BY 子句時,應注意以下問題:

  • GROUP BY子句可以包含任意數目的列,但每一列都必須是檢索列或有效的表達式(但不能是聚集函數),且不能使用別名。
  • 除聚集計算語句外,SELECT語句中的每一列都必須在GROUP BY子句中給出。
  • 如果分組列中包含具有NULL值的行,則NULL將作為一個分組返回。如果列中有多行NULL值,它們將分為一組

(2)使用HAVING 子句過濾分組

除了能用GROUP BY分組數據外,SQL還允許過濾分組,規定包括哪些分組,排除哪些分組。例如,在上例中,我們已使用GROUP
BY子句根據供應商進行數據分組,並返回每個供應商有多少個產品。現如果只想返回有三個產品以上的供應商:

    SELECT vend_id, COUNT(*) AS num_prods
    FROM Products
    GROUP BY vend_id
    HAVING COUNT(*) >= 3;
    
    GROUP BY子句根據供應商進行數據分組,HAVING 子句過濾並返回三個產品以上的供應商

從以上例子可以看出,HAVING子句和WHERE子句功能相似,有關WHERE的所有用法(包括通配符條件和帶多個操作符的子句)都適用於HAVING。唯一的差別是,WHERE過濾行,而HAVING過濾分組。

當然,我們也可以在一條語句中同時使用WHERE和HAVING子句:

    SELECT vend_id, COUNT(*) AS num_prods
    FROM Products
    WHERE prod_price >= 4
    GROUP BY vend_id
    HAVING COUNT(*) >= 3;
    
    和上述例子相比,多增加了一條WHERE子句,過濾所有prod_price至少為4的行

加上WHERE子句,輸出結果少了一行,因為供應商DLL01銷售4個產品,但價格都在4以下。

至此,回顧一下SELECT語句中子句的順序:

子查詢

本小節將會介紹什么是子查詢,如何使用它們。

(1)利用子查詢進行過濾

首先考察以下問題:本教程中使用的數據庫表都是關系表,其中關於訂單的信息存儲在兩個表中:Orders表存儲訂單編號、客戶ID、訂單日期;OrderItems表存儲各訂單的具體包含物品;顧客的實際信息存儲在Customers表中。

現在,假如需要列出訂購物品RGAN01的所有顧客,應該怎樣檢索?下面列出了具體步驟:

  1. 檢索包含物品RGAN01的所有訂單的編號;
  2. 檢索具有前一步驟列出的訂單編號的所有顧客的ID;
  3. 檢索前一步驟返回的所有顧客ID的顧客信息。

上述每個步驟都可以單獨作為一個查詢來執行。可以把一條SELECT語句返回的結果用於另一條SELECT語句的WHERE子句。第一條SELECT語句較為簡單:

    SELECT order_num
    FROM OrderItems
    WHERE prod_id = 'RGAN01';
    
    對prod_id為RGAN01的所有訂單物品,檢索其order_num列

現在我們知道了訂單編號,只需查詢與訂單20007和20008相關的顧客ID:

    SELECT cust_id
    FROM Orders
    WHERE order_num IN (20007,20008);
    
    檢索與訂單20007和20008相關的顧客ID

現在,結合這兩個查詢,把第一個查詢變為子查詢:

    SELECT cust_id
    FROM Orders
    WHERE order_num IN (SELECT order_num
                            FROM OrderItems
                            WHERE prod_id = 'RGAN01');
    
    檢索訂單中包含物品RGAN01的顧客ID
[/code]

![](http://onztfc060.bkt.clouddn.com/markdown-img-paste-20171010231207191.png)

現在得到了訂購物品RGAN01的所有顧客的ID,第三步是檢索這些顧客ID的顧客信息:

```code
    SELECT cust_name, cust_contact
    FROM Customers
    WHERE cust_id IN ('1000000004','1000000005');
    
    檢索這些顧客ID為1000000004和1000000005的顧客信息

仿照上例,把其中的WHERE子句轉換為子查詢:

    SELECT cust_name, cust_contact
    FROM Customers
    WHERE cust_id IN (SELECT cust_id
                         FROM orders
                         WHERE order_num IN (SELECT order_num
                                                FROM OrderItems
                                                WHERE prod_id = 'RGAN01'));
    
    檢索訂購物品RGAN01的所有顧客

為了執行上述SELECT語句,MySQ實際上必須執行三條SELECT語句。最里邊的子查詢返回訂單號列表,此列表用於其外面的子查詢的WHERE子句。外面的子查詢返回顧客ID列表,此顧客ID列表用於最外層查詢的WHERE子句。最外層查詢返回所需的數據。

可見,在WHERE子句中使用子查詢能夠編寫出功能很強且很靈活的SQL語句。對於能嵌套的子查詢的數目沒有限制,不過在實際使用時由於性能的限制,不能嵌套太多的子查詢。並且使用子查詢並不總是執行這種類型的數據檢索的最有效的方法,后續學習連接(JOIN)時我們還會遇到這個例子。

(2)作為計算字段使用子查詢

使用子查詢的另一方法是創建計算字段。假如需要顯示Customers表中每個顧客的訂單總數,其中訂單與相應的顧客ID存儲在Orders表中。執行這個操作,要遵循下面的步驟:

  1. 從Customers表中檢索顧客列表;
  2. 對於檢索出的每個顧客,統計其在Orders表中的訂單數目。
    實現如下:
    SELECT cust_name,
           cust_state,
           (SELECT COUNT(*)
            FROM Orders
            WHERE Orders.cust_id = Customers.cust_id) AS orders
    FROM Customers
    ORDER BY cust_name;
    
    SELECT COUNT(*)對表中的行進行計數,並且通過提供一條WHERE子句來過濾某個特定的顧客ID,僅對該顧客的訂單進行計數。最外層外層查詢對每個顧客執行COUNT(*)。

注意到子查詢中的WHERE子句與前面使用的WHERE子句稍有不同,因為它使用了完全限定列名(Orders.cust_id和Customers.cust_id),將Orders表中的cust_id和當前正從Customers表中檢索的cust_id進行比較。它的語法是用一個句點分隔表名和列名。當有可能混淆列名時,就必須使用完全限定列名來避免歧義。

JOIN和UNION查詢

我們知道,作為關系數據庫管理系統(RDBMS)一部分的關系數據庫,是用相互之間存在關系的表來組織數據的。下圖展示了本教程所使用的五張表之間的關系:

我們曾在“導入樣例表”小節中對這五張表的內容及其關系的進行了詳細地描述。雖然可以建一張更大的表來存儲所有的訂單和客戶細節,但是使用五張表有其優點:

  • 第一個優點是節省存儲空間。同一供應商生產的每個產品,其供應商信息都是相同的,對每個產品重復此信息既浪費時間又浪費存儲空間;
  • 另一個優點是容易進行變更與修正。如果供應商信息發生變化,例如供應商遷址或電話號碼變動,只需修改一次即可;
  • 第三個優點是,數據不重復使得處理數據和生成報表更簡單。如果有重復數據(即每種產品都存儲供應商信息),則很難保證每次輸入該數據的方式都相同。

簡而言之,關系表的設計就是要把信息分解成多個表,各表通過某些共同的值互相關聯,從而更有效地存儲以及更方便地處理。但在實際當中,經常有必要一次性跨多個表來訪問相關數據。為了完成這一任務,SQL查詢語句使用JOIN語句來指定多個表之間的關系。

JOIN連接

(1)內連接

連接(JOIN)使數據庫用戶能夠從2個或多個表中選擇適當的列。下面的SQL查詢給出了一個最常見類型的連接示例:內連接(inner join).

    SELECT vend_name, prod_name, prod_price
    FROM Vendors AS V
    INNER JOIN Products AS P
          ON V.vend_id = P.vend_id;     
    
    從Vendors和Products兩張表中返回各個供應商所提供的產品和價格

上面語句中,INNER
JOIN將Vendors和Products兩表關聯,關聯需要一個或多個字段作為連接橋梁。例子中的橋梁就是vend_id,我們使用on語句,將Vendors表的vend_id字段和Products的id字段匹配。

這里需要注意的是,因為字段可能重名,所以需要使用完全限定名以避免歧義。此外,表Vendors和Products分別使用AS關鍵字定義了別名V和P。用別名來代替完整的表明以提高查詢的可讀性。

在“子查詢”該小節中,我們曾用以下子查詢語句來檢索訂購物品RGAN01的所有顧客:

    SELECT cust_name, cust_contact
    FROM Customers
    WHERE cust_id IN (SELECT cust_id
                         FROM orders
                         WHERE order_num IN (SELECT order_num
                                                FROM OrderItems
                                                WHERE prod_id = 'RGAN01'));

現在我們使用連接三個表來執行相同查詢:

    SELECT cust_name, cust_contact
    FROM Customers, Orders, OrderItems
    WHERE Customers.cust_id = Orders.cust_id
     AND OrderItems.order_num = Orders.order_num
     AND prod_id = 'RGAN01';
    
    檢索訂購物品RGAN01的所有顧客

這個查詢中的返回數據需要使用3個表。但在這里,我們沒有在嵌套子查詢中使用它們,而是使用了兩個WHERE子句條件來連接表。第三個WHERE子句條件過濾產品RGAN01的數據。

(2)外連接

如上所述,在所有連接類型中,Inner
Join(內連接)最常見,可以縮寫成Join,找的是兩張表共同擁有的字段。但假設我們想對每個顧客下的訂單進行計數,包括那些至今尚未下訂單的顧客,這就需要包含那些在相關表中沒有關聯行的行。這種連接稱為外連接(OUTER
JOIN)。

外連接語法與內連接類似,但必須使用RIGHT或LEFT關鍵字指定包括其所有行的表(LEFT指出的是OUTER
JOIN左邊的表,而RIGHT指出的是OUTER JOIN右邊的表)。下面的例子使用LEFT OUTER
JOIN從FROM子句左邊的表(Customers表)中選擇所有行:

    SELECT Customers.cust_id, Orders.order_num
    FROM Customers LEFT OUTER JOIN Orders
     ON Customers.cust_id = Orders.cust_id;
    
    檢索包括沒有訂單顧客在內的所有顧客

輸出結果中,cust_id為1000000002那一行的Order_num為空,就是因為cust_id無法匹配上,返回了Null。如果改成Inner
Join,則不會返回整個cust_id為1000000002所在行。這是Inner Join和Left Join的區別。

另外一種基本的外連接形式是RIGHT OUTER
JOIN。它們之間的唯一差別是所關聯的表的順序。換句話說,調整FROM或WHERE子句中表的順序,左外聯結可以轉換為右外聯結。如A LEFT JOIN B
等價於 B RIGHT JOIN A因此,這兩種外聯結可以互換使用,哪個方便就用哪個。

UNION組合查詢

多數SQL查詢只包含從一個或多個表中返回數據的單條SELECT語句。但是,SQL也允許利用UNION操作符來組合多條SELECT語句,並將結果作為一個查詢結果集返回。這些組合查詢通常稱為並(union)或復合查詢(compound
query)。

主要有兩種情況需要使用組合查詢:

  • 在一個查詢中從不同的表返回結構數據;
  • 對一個表執行多個查詢,按一個查詢返回數據。

使用UNION很簡單,只需在各條SELECT語句之間放上關鍵字UNION:

    SELECT cust_name, cust_contact, cust_email
    FROM Customers
    WHERE cust_state IN ('IL','IN','MI')
    UNION
    SELECT cust_name, cust_contact, cust_email
    FROM Customers
    WHERE cust_name = 'Fun4All';
    
    檢索Illinois、Indiana和Michigan等美國幾個州的所有顧客的報表,以及包括不管位於哪個州的所有的Fun4All。

第一條SELECT把Illinois、Indiana、Michigan等州的縮寫傳遞給IN子句,檢索出這些州的所有行。第二條SELECT利用簡單的相等測試找出所有Fun4All。兩條SELECT語句之間用UNION關鍵字分隔。

上述UNION語句從查詢結果集中自動去除了重復的行,例如Indiana州有一個Fun4All單位,所以兩條SELECT語句都返回該行。使用UNION時,重復的行會被自動取消。但如果想返回所有的匹配行,可使用UNION
ALL代替UNION:

    SELECT cust_name, cust_contact, cust_email
    FROM Customers
    WHERE cust_state IN ('IL','IN','MI')
    UNION ALL
    SELECT cust_name, cust_contact, cust_email
    FROM Customers
    WHERE cust_name = 'Fun4All';
    
    檢索Illinois、Indiana和Michigan等美國幾個州的所有顧客的報表,以及包括不管位於哪個州的所有的Fun4All。不取消重復的行。

使用組合查詢時需要注意的是:

  • UNION中的每個查詢必須包含相同的列、表達式或聚集函數(不過,各個列不需要以相同的次序列出);
  • 在上述簡單的例子中,可使用WHERE子句代替UNION完成同樣的功能。但對於較復雜的過濾條件,或者從多個表(而不是一個表)中檢索數據的情形,使用UNION可能會使處理更簡單。且如果需要每個條件的匹配行全部出現(包括重復行),就必須使用UNION ALL。

數據管理

毫無疑問,SELECT是在作數據庫內分析時最常用的SQL語句,因此,我們在第二部分和第三部分着重介紹了SELECT語句的相關用法。在第四部分中,我們將繼續介紹其他3個常用的SQL語句。

插入數據

INSERT用來將一行或多行插入到數據庫表。插入有幾種方式:

  • 插入完整的行;
  • 插入行的一部分;
  • 插入某些查詢的結果。

(1)插入完整的行
基本的INSERT語法要求指定表名和插入到新行中的值,例如:

    INSERT INTO Customers
    VALUES('1000000006',
           'Toy Land',
           '123 Any Street',
           'New York',
           'NY',
           '11111',
           'USA',
           NULL,
           NULL);

這個例子將一個新顧客插入到Customers表中。存儲到表中每一列的數據在VALUES子句中給出。如果某列沒有值,如上面的cust_contact和cust_email列,則應該使用NULL值(如果表允許對該列指定空值)。

雖然這種語法很簡單,但高度依賴於表中列的定義次序,並不安全,應該盡量避免使用。更安全的寫法應在表名后的括號里明確給出列名。如下所示:

    INSERT INTO Customers(cust_id,
                          cust_name,
                          cust_address,
                          cust_city,
                          cust_state,
                          cust_zip,
                          cust_country,
                          cust_contact,
                          cust_email)
     VALUES('1000000006',
           'Toy Land',
           '123 Any Street',
           'New York',
           'NY',
           '11111',
           'USA',
           NULL,
           NULL);

(2)插入部分行
如果已經在表名后的括號里明確給出了列名,則可以只插入部分行:

    INSERT INTO Customers(cust_id,
                          cust_name,
                          cust_address,
                          cust_city,
                          cust_state,
                          cust_zip,
                          cust_country,
                          cust_contact,
                          cust_email)
     VALUES('1000000006',
           'Toy Land',
           '123 Any Street',
           'New York',
           'NY',
           '11111',
           'USA',
           NULL,
           NULL);

但需要注意省略的列必須滿足以下條件:該列定義為允許NULL值或已給出默認值。否則MySQL將產生錯誤消息,相應的行不能成功插入。

(3)插入檢索出的數據
INSERT一般用來給表插入具有指定列值的行。但可以利用它將SELECT語句的結果插入表中,這就是所謂的INSERT
SELECT。顧名思義,它是由一條INSERT語句和一條SELECT語句組成的。假如想把另一表中的顧客列合並到Customers表中。不需要每次讀取一行再將它用INSERT插入,可以如下進行::

    INSERT INTO Customers(cust_id,
                          cust_contact,
                          cust_email,
                          cust_name,
                          cust_address,
                          cust_city,
                       cust_state,
                          cust_zip,
                          cust_country)
    SELECT cust_id,
           cust_contact,
           cust_email,
           cust_name,
           cust_address,
           cust_city,
           cust_state,
           cust_zip,
           cust_country
    FROM CustNew;

這個例子使用INSERT
SELECT從CustNew中將所有數據導入Customers。SELECT中列出的每一列對應於Customers表名后所跟的每一列。為簡單起見,這個例子在
INSERT 和SELECT 語句中使用了相同的列名。但其實MySQL使用的是列的位置,SELECT
中的第一列將用來填充表列中指定的第一個列,第二列對應第二列,以此類推。這對於從使用不同列名的表中導入數據是非常有用的。

更新和刪除數據

(1)更新數據

為了更新表中的數據,可使用 UPDATE 語句。基本的UPDATE語句由三部分組成:

  • 要更新的表;
  • 列名和它們的新值;
  • 確定要更新哪些行的過濾條件。

例如,客戶1000000005現在有了電子郵件地址,因此他的記錄需要更新,語句如下:

    UPDATE Customers
    SET cust_email = 'kim@thetoystore.com'
    WHERE cust_id = '1000000005';

UPDATE語句總是以要更新的表名開始,SET命令用來將新值賦給被更新的列,最后以WHERE子句結束。沒有WHERE子句,DBMS將會用這個電子郵件地址更新Customers表中的所有行,這不是我們希望的。

要更新多個列時,只需要使用一條SET命令,每個“列=值”對之間用逗號分隔:

    UPDATE Customers
    SET cust_contact = 'Sam Roberts',
        cust_email = 'sam@toyland.com'
    WHERE cust_id = '1000000006';

要刪除某個列的值時,可設置它為NULL(假如表定義允許NULL值):

    UPDATE Customers
    SET cust_email = NULL
    WHERE cust_id = '1000000005';

注:更新數據時一定要細心,不要省略WHERE子句,否則稍不注意,就會更新表中的所有行。

(2)刪除數據

使用DELETE語句可從一個表中刪除數據,包括從表中刪除特定的行甚至所有行。例如,從Customers表中刪除一位顧客:

    DELETE FROM Customers
    WHERE cust_id = '1000000006';

DELETE FROM 指定從中刪除數據的表名。WHERE 子句過濾要刪除的行。如果省略 WHERE 子句,它將刪除表中每個客戶。

DELETE 刪除整行而不是刪除列。如需刪除指定的列,可使用上述 UPDATE 語句。

注:刪除數據時同樣需要小心,因為如果執行 DELETE 語句而不帶 WHERE 子句,表的所有數據都將被刪除且不可恢復。此外,在對 UPDATE 或
DELETE 語句使用 WHERE 子句前,應該先用 SELECT 進行測試,以保證它過濾的是正確的記錄。

小結

SQL作為當前使用最為廣泛的數據庫語言,已經成為數據工程師的必備技能之一。這份學習指南的第一部分介紹了數據庫、SQL和MySQL的基本概念,完成了SQL環境的基本搭建。第二部分和第三部分介紹了如何使用SELECT語句進行數據查詢,包括排序、過濾、分組、子查詢等基本方法、函數的使用以及如何使用JOIN和UNION查詢一次性跨多個表來訪問相關數據。最后一部分還介紹了數據管理的基本操作,包括插入、更新和刪除數據等。

本文作者: heming
本文鏈接: [ SQL簡明數據分析教程

](https://heming6666.github.io/2017/10/10/SQL簡明數據分析教程/)
版權聲明: 本博客所有文章除特別聲明外,均采用 CC BY-NC-SA 3.0 許可協議。轉載請注明出處!

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM