MySQL必知必會(一)


這本書從簡單的數據檢索開始,逐步引入一些複雜的內容,包括聯結的使用、子查詢、正則表達式和基於全文本的搜索,存儲過程、遊標、觸發器、表約束等等。

1. 瞭解SQL

1.1 什麼是數據庫

數據庫(database):保存有組織的數據的容器(通常是一個文件或一組文件)。

數據庫軟件被稱爲DBMS(數據庫管理系統),數據庫是通過DBMS創建和操縱的容器。

數據庫和數據庫軟件的關係:使用 DBMS 來訪問數據庫。

:某種特定類型數據的結構化清單。
表名:在相同的數據庫中不能兩次使用相同的表名,但在不同的數據庫中卻可以使用相同的表名。
模式:關於數據庫和表的佈局及特性的信息。
:表中的一個字段,所有表都是由一個或多個列組成的。
數據類型:所容許的數據的類型。每個表列都用相應的數據類型。
:表中的一個記錄。

主鍵:一列(或一組列),其值能夠唯一區分表中每個行。
表中的任何列都可以作爲主鍵,只要它滿足以下條件:
 任意兩行都不具有相同的主鍵值;
 每個行都必須具有一個主鍵值(主鍵列不允許NULL值)。

1.2 什麼是SQL

SQL是結構化查詢語言,是一種專門與數據庫通信的語言。

2. MySQL簡介

2.1 什麼是MySQL

MySQL是一種DBMS,它是一種數據庫管理軟件。

DBMS可以分爲兩類:一類是基於共享文件系統的DBMS,另一類是基於客戶機–服務器的DBMS。、

MySQL、 Oracle以及Microsoft SQL Server等數據庫是基於客戶機—服務器的數據庫。客戶機—服務器應用分爲兩個不同的部分。 服務器部分是負責所有數據訪問和處理的一個軟件。這個軟件運行在稱爲數據庫服務器的計算機上。客戶機是與用戶打交道的軟件。

MySQL的當前版本爲版本5(許多公司正在使用MySQL 3 和4)。
下面是最近版本中引入的主要更改。
 4——InnoDB引擎,增加事務處理(第26章)、並(第17章)、改進全文本搜索(第18章)等的支持。
 4.1——對函數庫、子查詢(第14章)、集成幫助等的重要增加。
 5——存儲過程(第23章)、觸發器(第25章)、遊標(第24章)、
視圖(第22章)等。
版本4.1和版本5對MySQL增加了重要的功能。

使用時:
 命令輸入在mysql>之後;
 命令用;或\g結束,換句話說,僅按Enter不執行命令;
 輸入help或\h獲得幫助,也可以輸入更多的文本獲得特定命令的
幫助(如,輸入help select獲得使用SELECT語句的幫助);
 輸入quit或exit退出命令行實用程序。

3. 使用MySQL

3.1 連接

MySQL與所有客戶機—服務器DBMS一樣,要求在能執行命令之前登錄到DBMS。

登錄之後可實現一些基本操作:

#顯示數據庫
show databases;
#使用某一個數據庫
use test;
#顯示該數據庫中的表
show tables;
#顯示某個表的表列
show columns from customers;
#還可以使用describe來顯示錶列
describe customers;
#顯示廣泛的服務器狀態信息
show status;
#用來顯示授予用戶(所有用戶或特定用戶)的安全權限
show grants;
#顯示服務器錯誤消息
show errors;
#顯示服務器警告消息
show warnings;
#顯示允許的show語句
help show;

4. 檢索數據

4.1 select 語句

1. 普通檢索

# 檢索單個列
select prod_name from products;
# 檢索多個列
select pro_id, prod_name, prod_price from products;
# 檢索所有的列
select * from products;

2. distinct關鍵字

# distinct表示只返回唯一的值,它只能放在列名的前面
#使用時注意distinct關鍵字應用於所有的列而不僅是它前置的列
select distinct ven_id from products;

3. 限制結果

# 下面的語句表示返回前5行(不超過5行)
select prod_name from products limit 5;
# 下面的語句表示從第4行(行3)開始,返回5行
select prod_name from products limit 3, 5;

帶一個值的LIMIT總是從第一行開始,給出的數爲返回的行數。
帶兩個值的LIMIT可以指定從行號爲第一個值的位置開始。

行0 檢索出來的第一行爲行0而不是行1。因此, LIMIT 1, 1
將檢索出第二行而不是第一行。

4. 使用完全限定的表名

select products.prod_name from crashcourse.products;

5. 排序檢索數據

5.1 排序數據

使用 order by

select prod_name from products order by prod_name;

通過非選擇列進行排序 通常, ORDER BY子句中使用的列將是爲顯示所選擇的列。但是,實際上並不一定要這樣,用非檢索的列排序數據是完全合法的。

5.2 按多個列排序

select prod_name, prod_price, prod_name from products 
order by prod_price, prod_name;

5.3 指定排序方向

默認爲ASC(ASCENDING)升序,可以不設置,而降序需要設置爲DESC。

#按價格以降序排序產品(最貴的排在最前面)
select pro_id, prod_price, prod_name from products 
order by prod_price DESC;

#以降序排序產品(最貴的在最前面),然後再對產品名排序
select pro_id, prod_price, prod_name from products 
order by prod_price DESC,prod_name;

#使用ORDER BY和LIMIT的組合,能夠找出一個列中最高或最低的值
select prod_price from products order by prod_price DESC 
limit 1;

6. 過濾數據

使用where語句指定搜索條件

# 查找價格爲2.50的行
select prod_name, prod_price from products 
where prod_price = 2.50;
# 查找不是由供應商1003製造的所有產品
select vend_id, prod_name from products 
where vend_id <> 1003;
# between 的使用
select prod_name, prod_price from products 
where prod_price between 5 and 10;

# 空值檢查
select prod_name from products where prod_price is null; 

需要注意:在同時使用ORDER BY和WHERE子句時,應該讓ORDER BY位於WHERE之後, 否則將會產生錯誤。
在這裏插入圖片描述

7. 數據過濾

組合where字句,這些子句可以兩種方式使用:以AND子句的方式或OR子句的方式使用。

需要注意:and操作符的優先級高於or,因此在同時使用時可以根據情況加上括號

# and 操作符
select prod_id, prod_price, prod_name from products 
where vend_id = 1003 and prod_price <= 10;

# or 操作符
select prod_name, prod_price from products 
where vend_id = 1002 or vend_id = 1003;

# and 和 or 同時使用
select prod_name, prod_price from products 
where (vend_id = 1002 or vend_id  = 1003) and prod_price 
>= 10;

# in 操作符
select prod_name, prod_price from products 
where vend_id in1002,1003order by prod_name;

# not 操作符
select prod_name, prod_price from products 
where vend_id not in1002,1003order by prod_name;

爲什麼要使用IN操作符?其優點具體如下。
 在使用長的合法選項清單時, IN操作符的語法更清楚且更直觀。
 在使用IN時,計算的次序更容易管理(因爲使用的操作符少)。
 IN操作符一般比OR操作符清單執行更快。
 IN的最大優點是可以包含其他SELECT語句,使得能夠更動態地建立WHERE子句。

WHERE子句中的NOT操作符有且只有一個功能,那就是否定它之後所跟的任何條件。

MySQL中的 NOT MySQL 支 持 使 用 NOT 對 IN 、 BETWEEN 和EXISTS子句取反,這與多數其他DBMS允許使用NOT對各種條件取反有很大的差別。

8. 用通配符進行過濾

# % 通配符
# 表示搜索以jet開頭的數據所在的行
select prod_id,prod_name from products where prod_name like 'jet%';

# 搜索包含文本anvil的數據所在的行
select prod_id,prod_name from products where prod_name like '%anvil%';

# 下劃線 _ 通配符(只匹配單個字符)
select prod_id,prod_name from products where prod_name like 
'_ ton anvil';

9. 用正則表達式進行搜索

隨着過濾條件的複雜性的增加, WHERE子句本身的複雜性也有必要增加。

這也就是正則表達式變得有用的地方。正則表達式是用來匹配文本的特殊的串(字符集合)。如果你想從一個文本文件中提取電話號碼,可以使用正則表達式。如果你需要查找名字中間有數字的所有文件,可以使用一個正則表達式。如果你想在一個文本塊中找到所有重複的單詞,可以使用一個正則表達式。如果你想替換一個頁面中的所有URL爲這些URL的實際HTML鏈接, 也可以使用一個正則表達式或者是兩個正則表達式。

1. 基本字符匹配

關鍵字 regexp

# 檢索出列prod_name包含文本1000的所有行
select prod_name from products 
where prod_name regexp '1000' 
order by prod_name;

在這裏插入圖片描述
r如果要把包含1000的都找到,使用下面的語句

regexp '.000’

# 檢索出列prod_name包含文本000的所有行
select prod_name from products 
where prod_name regexp '.000' 
order by prod_name;

匹配不區分大小寫 MySQL中的正則表達式匹配(自版本3.23.4後)不區分大小寫(即,大寫和小寫都匹配)。爲區分大小寫,可使用BINARY關鍵字,如 WHERE prod_name REGEXP BINARY ‘JetPack .000’。

2. 進行 or 匹配

select prod_name from products 
where prod_name regexp '1000|2000' 
order by prod_name; 

在這裏插入圖片描述

select prod_name from products 
where prod_name regexp '[123] Ton' 
order by prod_name; 

在這裏插入圖片描述
這裏,使用了正則表達式[123] Ton。 [123]定義一組字符,它的意思是匹配1或2或3,因此, 1 ton 和2 ton 都匹配且返回(沒有3 ton)。

字符集合也可以被否定,即,它們將匹配除指定字符外的任何東西。爲否定一個字符集,在集合的開始處放置一個^即可。因此,儘管[123]匹配字符1、 2或3,但 [ ^123]卻匹配除這些字符外的任何東西。

3. 匹配範圍

select prod_name from products 
where prod_name regexp '[1-5] Ton' 
order by prod_name; 

在這裏插入圖片描述

4. 匹配特殊字符

爲了匹配特殊字符,必須用\爲前導。\-表示查找-, \.表示查找.。

select prod_name from products 
where prod_name regexp '\\.' 
order by prod_name; 

在這裏插入圖片描述

5. 匹配字符類

在這裏插入圖片描述

6. 匹配多個實例

加粗樣式
在這裏插入圖片描述

7. 定位符

在這裏插入圖片描述

10. 創建計算字段

1. 拼接

拼接:將值聯結到一起構成單個值。

解決辦法是把兩個列拼接起來。在MySQL的SELECT語句中,可使用Concat()函數來拼接兩個列。

select concat(vend_name, ' (', vend_country, ')') 
from vendors order by vend_name;

在這裏插入圖片描述
**Concat()**拼接串,即把多個串連接起來形成一個較長的串。

**Concat()**需要一個或多個指定的串,各個串之間用逗號分隔。上面的SELECT語句連接以下4個元素:
 存儲在vend_name列中的名字;
 包含一個空格和一個左圓括號的串;
 存儲在vend_country列中的國家;
 包含一個右圓括號的串。

Trim函數 MySQL除了支持RTrim()(正如剛纔所見,它去掉串右邊的空格),還支持LTrim()(去掉串左邊的空格)以及Trim()(去掉串左右兩邊的空格)

select concat(rtrim(vend_name), ' (', rtrim(vend_country), ')') as vend_title from vendors order by vend_name;

在這裏插入圖片描述

2. 執行算術計算

檢索訂單號20005中的所有物品

select prod_id, quantity, item_price from orderitems 
where order_num = 20005;

在這裏插入圖片描述
item_price列包含訂單中每項物品的單價。如下彙總物品的價格(單
價乘以訂購數量):

select prod_id, quantity, item_price, quantity*item_price as 
expended_price from orderitems where order_num = 20005;

在這裏插入圖片描述
在這裏插入圖片描述
如何測試計算 SELECT提供了測試和試驗函數與計算的一個很好的辦法。雖然SELECT通常用來從表中檢索數據,但可以省略FROM子句以便簡單地訪問和處理表達式。例如, SELECT3*2;將返回6, SELECT Trim(‘abc’);將返回abc,而SELECTNow()利用Now()函數返回當前日期和時間。通過這些例子,可以明白如何根據需要使用SELECT進行試驗。

11. 使用數據處理函數

1. 文本處理函數

select vend_name,Upper(vend_name) as vend_name_upcase 
from vendors order by vend_name;

在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述

2. 日期和事件處理函數

MySQL使用的日期格式。無論你什麼時候指定一個日期,不管是插入或更新表值還是用WHERE子句進行過濾,日期必須爲格式yyyy-mm-dd。因此, 2005年9月1日,給出爲2005-09-01。
在這裏插入圖片描述
如果要的是日期,請使用Date() 如果你想要的僅是日期,則使用Date()是一個良好的習慣,即使你知道相應的列只包含日期也是如此。這樣,如果由於某種原因表中以後有日期和時間值,你的SQL代碼也不用改變。

select cust_id, order_num from orders 
where date(order_date) = '2005-09-01';

select cust_id, order_num from orders 
where date(order_date) between '2005-09-01' and '2005-09-30';

# 還有另外一種辦法(一種不需要記住每個月中有多少天或不需要操心閏年2月的辦法):
select cust_id, order_num from orders 
where year(order_date)  =  2005' and month(order_date) = 9;

3. 數值處理函數

在這裏插入圖片描述

12. 彙總數據

1. 聚集函數

聚集函數:運行在行組上,計算和返回單個值的函數。
在這裏插入圖片描述

COUNT()函數有兩種使用方式。
‰ 使用COUNT(*)對錶中行的數目進行計數, 不管表列中包含的是空值(NULL)還是非空值。
‰ 使用COUNT(column)對特定列中具有值的行進行計數,忽略NULL值。

select avg(prod_price) as avg avg_price 
from products where vend_id = 1003;

select count(*) as num_cust from customers;

select max(prod_price) as max_price from products;

select min(prod_price) as min_price from products;

select sum(quantity) as items_ordered from orderitems 
where order_num = 20005;

select sum(item_price*quantity) as total_price from orderitems 
where order_num = 20005;

2. 聚集不同的值

聚集函數中 distinct 的使用:

distinct必須使用列名,不能用於計算或表達式。

select avg(distinct prod_price) as avg_price from products 
where vend_id = 1003;

3. 組合聚集函數

select count(*) as num_items, 
min(prod_price) as price_min, 
max(prod_price) as price_max, 
avg(prod_price) as price_avg, 
from products;

13. 分組數據

1. 分組 group by

GROUP BY子句必須出現在 WHERE 子句之後, ORDER BY 子句之前。
在這裏插入圖片描述
where 和 having 的區別:

WHERE過濾行,而HAVING過濾分組。也就是說WHERE在數據分組前進行過濾, HAVING在數據分組後進行過濾。這是一個重要的區別, WHERE排除的行不包括在分組中。
在這裏插入圖片描述
在這裏插入圖片描述
2. 排序 group by 和 order by
在這裏插入圖片描述
一般在使用GROUP BY子句時,應該也給出ORDER BY子句。這是保證數據正確排序的唯一方法。千萬不要僅依賴GROUP BY排序數據。

在這裏插入圖片描述

14. 使用子查詢

1. 利用子查詢進行過濾

在這裏插入圖片描述
最裏邊的子查詢返回訂單號列表,此列表用於其外面的子查詢的WHERE子句。外面的子查詢返回客戶ID列表,此客戶ID列表用於最外層查詢WHERE子句。最外層查詢確實返回所需的數據。

列必須匹配 在WHERE子句中使用子查詢(如這裏所示),應該保SELECT語句具有與WHERE子句中相同數目的列。通常,子查詢將返回單個列並且與單個列匹配,但如果需要也可以使用多個列。

2. 作爲計算字段使用子查詢

在這裏插入圖片描述
這 條 SELECT 語 句 對 customers 表 中 每 個 客 戶 返 回 3 列: cust_name、 cust_state和orders。 orders是一個計算字段,它是由圓括號中的子查詢建立的。該子查詢對檢索出的每個客戶執行一次。在此例子中,該子查詢執行了5次,因爲檢索出了5個客戶。

子查詢中的WHERE子句與前面使用的WHERE子句稍有不同,因爲它使用了完全限定列名(在第4章中首次提到)。下面的語句告訴SQL比較orders表中的cust_id與當前正從customers表中檢索的cust_id:

where orders.cust_id = customers.cust_id
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章