MySQL必知必會 瞭解SQL 什麼是資料庫: 資料庫(database)保存有阻止的數據的容器,可以把資料庫想象成一個文件櫃。 什麼是表: 表(table) 某種特定類型結構的結構化清單,資料庫中的表的名字是唯一的。 什麼是列: 列(column)表中的一個欄位。所有表都是有一個或多個列組成的 ...
MySQL必知必會
瞭解SQL
什麼是資料庫:資料庫(database)保存有阻止的數據的容器,可以把資料庫想象成一個文件櫃。
什麼是表:表(table) 某種特定類型結構的結構化清單,資料庫中的表的名字是唯一的。
什麼是列:列(column)表中的一個欄位。所有表都是有一個或多個列組成的,理解列的最好辦法是將資料庫表想象為一個網格,網格中每一列存儲著一條特定信息。例如,編號,地址,郵政編碼。
什麼是行:行(row) 表中的數據是按行存儲的,所保存的每個記錄存儲在自己的行內,例如,每一行存儲一個顧客。
什麼是主鍵:主鍵(primary key ) 一列(或一組列)其值能夠唯一區分表中的每一行。唯一標識表中每行的這個列稱為主鍵。主鍵用來表示一個特定的行,沒有主鍵,更新或刪除特定的行很困難,因為沒有安全的方法保證只涉及相關的行。
什麼是SQL: SQL(發音為字母S-Q-L或sequel)是結構化查詢語言(Structured Query Language)的縮寫,SQL是一種專門用來與資料庫通信的語言。
檢索數據
SELECT語句:
檢索單個列:SELECT prod_name FROM products;
分析:上述語句利用SELECT語句從products表中檢索一個名為prod_name的列。所需的列名在SELECT關鍵字之後給出,FROM關鍵字指出從其中檢索數據的表名。
檢索多個列:SELECT prod_id,prod_name,prod_price FROM products;
分析:指定了3個列名,列名之間用逗號分隔,最後一個列名不加逗號
檢索所有列: SELECT * FROM products;
分析:如果給定了一個通配符(*),則返回表中的所有列。列的順序一般是列在表中定義出現的順序。但有時候並不是這樣的,表的模式的變化(如添加或刪除列),可能會導致順序變化
檢索不同的行:SELECT DISTINCT vend_id FROM products ;
分析:SELECT DISTINCT vend_id告訴MySQL只返回不同的vend_id行,如果使用DISTINCT關鍵字,必須放在列名的最前面
限制結果: SELECT pro_name FROM products LIMIT 5;
分析: 此語句使用SELECT語句檢索單個列,LIMIT 5指示MySQL返回不多於5行
為了得到下一個5行,可指定要檢索的開始行和行數: SELECT pro_name FROM products LIMIT 5 ,5
分析:LIMIT 5 , 5指示MySQL返回從行5開始的5行。第一個數為開始位置,第二個數為要檢索的行數。
註意:檢索從第0行開始
使用完全限定的表名:**完全限定(同時使用表名和列名)SELECT products.prod_name FROM products;
排序檢索數據
子句: SQL語句由子句構成,有些子句是必須的,而有的是可選的,
ORDER BY: SELECT prod_name FROM products ORDER BY prod_name
分析: 選擇prodects的prod_name列,對prod_name列按照字母升序
多個列排序: SELECT prod_id,pro_price,prod_name FROM products ORDER BY prod_price,prod_name;
分析: 僅在多個行具有相同的prod_price值時才對產品按prod_name進行排序。如果prod_price列中所有的值是唯一的,則不會按prod_name排序
指定排序方向: SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price DESC;
分析:以價格降序排序產品
多個列排序: SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price DESC,prod_name;
分析: DESC 關鍵字只應用到直接位於其前面的列名,prod_price列指定DESC,對prod_name列不指定。因此,prod_price列以降序排序,而prod_name仍然按標準的升序排序
如果想在多個列進行降序排序,必須對每個列指定DESC關鍵字
升序:ASC,預設值
過濾數據
只檢索所需數據需要指定搜索條件,搜索條件也稱為過濾條件
在SELECT語句中,數據根據WHERE子句中指定的搜索條件進行過濾,WHERE子句在表名(FROM子句)之後給出
輸入: SELECT prod_name,prod_price FROM products WHERE prod_price = 2.50;
分析: 這條語句從products表中檢索兩個列,但不返回所有行,只返回prod_price值為2.5的行
WHERE子句操作符
操作符 | 說明 |
= | 等於 |
<> | 不等於 |
!= | 不等於 |
< | 小於 |
<= | 小於等於 |
> | 大於 |
>= | 大於等於 |
BETWEEN | 在指定的兩個值之間 |
檢查單個值
輸入:SELECT prod_name,prod_price FROM products WHERE prod_name = 'fuses'
分析: 檢查WHERE prod_name='fuses'語句,他返回prod_name的值為Fuses的一行。MySQL在執行匹配時預設不區分大小寫
範圍值檢查
輸入: SELECT prod_name,prod_price FROM products WHERE prod_price BETWEEN 5 AND 10;
分析: 在使用BETWEEN時,必須指定兩個值;所需範圍的低端值和高端值,這兩個值必須用AND關鍵字分隔,BETWEEN匹配範圍中所有的值,包括指定的開始和結束值。
空值檢查
在創建表時,表設計人員可以指定其中的列是否可以不包含值,一個列不包含值時,稱其為包含空值NULL
輸入: SELECT prod_name FROM products WHERE prod_price IS NULL;
分析: 這條語句返回沒有價格的所有產品
數據過濾
AND操作符
為了通過不止一個列進行過濾,可以使用AND操作符給WHERE子句附加條件。下麵的代碼給出了一個例子:
輸入: SELECT prod_id,prod_price,prod_name FROM products WHERE vend_id = 1003 AND prod_price <= 10;
分析:此sql語句檢索由供應商1003製造且價格小於等於10美元的所有產品的名稱和價格。
AND:用在WHERE子句中的關鍵字,用來指示檢索滿足所有給定條件的行
上述例子中使用了只包含一個關鍵字AND的語句。把兩個過濾條件組合在一起。還可以添加多個過濾條件,每添加一條就要使用一個AND
OR操作符
OR操作符與AND操作符不同,他指示MySQL檢索任一條件的行
輸入: SELECT prod_name,prod_price FROM products WHERE vend_id = 1002 OR vend_id = 1003;
分析: 此SQL語句檢索由任一指定供應商的所有產品的產品名和價格。OR操作符告訴DBMS匹配任一條件而不是同時匹配兩個條件。
計算次序
輸入: SELECT prod_name,prod_price FROM products WHERE( vend_id=1002 OR vend_id =1003) AND prod_price >=10;
分析: 圓括弧具有敲AND或OR操作符高的計算次序,DBMS首先過濾圓括弧內的OR條件。
IN操作符
圓括弧在WHERE子句中還有另外一種用法。IN操作符用來指定條件範圍,範圍中的每個條件都可以進行匹配。IN取合法值的由逗號分隔的清單全都在圓括弧中。
輸入: SELECT prod_name,prod_price FROM products WHERE vend_id IN(1002,1003) ORDER BY prod_name;
分析: 此SELECT語句檢索供應商1002和1003製造的所有產品。操作符後跟由逗號分隔的合法值清單,整個清單必須在圓括弧中
IN操作符與OR具有相同的功能
NOT操作符
WHERE子句中的NOT操作符有且只有一個功能,那就是否定他之後所跟的任何條件
NOT WHERE子句中用來否定後跟條件的關鍵字。
輸入: SELECT prod_name,prod_price FROM products WHERE vend_id NOT IN(1002,1003) ORDER BY prod_name;
分析: 這裡的NOT否定跟在他之後的條件,因此MySQL不是匹配1002和1003的vend_id,而是匹配1002和1003之外的供應商的
用通配符進行過濾
百分號(%)通配符
最常用的通配符是百分號(%)。在搜索串中,%表示任何字元出現的任意次數。例如,為了找出所有以詞jet開頭的產品,可以使用一下SELECT語句:
輸入: SELECT prod_id,prod_name FROM products WHERE prod_name LIKE 'jet%';
分析: 此例子使用了搜索模式'jet%',在執行這條子句時,將檢索任意以jet起頭的詞。%告訴MySQL接受jet之後的任意字元,不管他有多少字元
通配符可在搜索模式中任意位置使用,並且可以使用多個通配符,下麵的例子使用兩個通配符,他們位於模式的兩端:
輸入: SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '%anvil%';
分析: 搜索模式'%anvil%' 表示匹配任何位置包含文本anvil的值,不論他之前或之後出現什麼字元
**下劃線(_)通配符**
另一個有用的通配符是下劃線(_).下劃線的用途與%一樣,但下劃線只匹配單個字元而不是多個字元
輸入: SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '_ ton anvil';
分析: 與%能匹配0個字元不一樣,_總是匹配一個字元,不能多不能少
用正則表達式進行搜索
使用MySQL正則表達式
正則表達式的作用是匹配文本,將一個模式(正則表達式)與一個文本串進行比較,MySQL用WHERE子句對正則表達式提供了初步的支持,允許你指定正則表達式過濾SELECT檢索出的數據
基本字元匹配
輸入:SELECT prod_name FROM products WHERE prod_name REGEXP '1000' ORDER BY prod_name;
分析: 除了關鍵字LIKE被REGEXP替代外,這條語句非常像使用LIKE語句,他告訴MySQL:REGEXP後所跟的東西作為正則表達式(與文字正文1000匹配的一個正則表達式)處理
輸入: SELECT prod_name FROM products WHERE prod_name REGEXP '.000' ORDER BY prod_name;
分析: 這裡使用正則表達式.000 。.是正則表達式語言中一個特殊的 字元,他表示匹配任意一個字元。
示例:
mysql> SELECT NAME FROM account WHERE NAME REGEXP '.s' ORDER BY NAME;
+------+
| NAME |
+------+
| test |
| tsdf |
+------+
進行OR匹配
輸入: SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name;
分析: 語句中使用正則表達式1000|2000為正則表達式的OR操作符,他表示匹配其中之一,相當於OR語句。
匹配幾個字元之一
匹配任何單一字元,但是,如果你只想匹配特定的字元,可以通過指定一組用[和]括起來的字元來完成
輸入: 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)
示例:
mysql> SELECT NAME FROM account WHERE NAME REGEXP '[at]est' ORDER BY NAME;
+------+
| NAME |
+------+
| aest |
| test |
+------+
匹配範圍
集合可以用來定義要匹配的一個或多個字元,
輸入: SELECT prod_name FROM products WHERE prod_name REGEXP '[1-5]' Ton ORDER BY pord_name;
分析: 這裡使用正則表達式[1-5] Ton [1-5]定義了一個範圍,這個表達式的意思是匹配1到5
示例:
mysql> SELECT NAME FROM account WHERE NAME REGEXP '[a-z]cc' ORDER BY NAME;
+------+
| NAME |
+------+
| ccc |
| ccc |
+------+
匹配特殊字元
如何匹配 .、|、-等特殊字元
SELECT vend_name FROM vendors WHERE vend_name REGEXP ' \\.' ORDER BY vend_name;
分析:
\\.匹配.,這種處理方式稱之為轉義
匹配多個實例
重覆元字元
元字元 | 說明 |
---|---|
* | 0個或者多個匹配 |
+ | 1個或多個匹配(等於{1,}) |
? | 0個或1個匹配(等於{0,1}) |
{n} | 指定數目的匹配 |
{n,} | 不少於指定數目的匹配 |
{n,m} | 匹配數目的範圍(m不超過255) |
輸入:
SELECT prod_name FROM products WHERE prod_name REGEXP '\\([0-9] sticks?)' ORDER BY prod_name;
分析: sticks? 匹配stick和sticks,?表示0個或1個匹配
輸入:
SELECT prod_name FROM products WHERE prod_name REGEXP '[[:digit:]]{4}' ORDER BY prod_name;
分析: [:digit:]匹配任意數字 ,{4}:確切的要求他前面的字元(任意數字),出現4次,匹配prod_name文本中包含4個任意連在一起的數字
定位符
目前為止的所有例子都是匹配一個串中任意位置的文本,為了匹配特定位置的文本,需要使用定位符
元字元 | 說明 |
---|---|
^ | 文本的開始 |
$ | 文本的結尾 |
[[:<:]] | 詞的開始 |
[[:>:"]] | 詞的結尾 |
示例
mysql> SELECT NAME FROM account WHERE NAME REGEXP '[[:<:]]t' ORDER BY NAME;
+------+
| NAME |
+------+
| t57L |
| test |
| tsdf |
創建計算欄位
拼接欄位
vendors表包含供應商和位置信息。假如要生成一個供應商報表,需要在供應商的名字中按照name(location)這樣的格式列出供應商的位置
解決辦法是把兩個列拼接起來,在MySQL的SELECT語句中,可以使用Concat()函數拼接兩個列
輸入: SELECT Concat(vend_name,'(',vend_country,')') FROM vendors ORDER BY vend_name;
分析: Concat()拼接串,既把多個串連接起來形成一個較長的串
示例:
mysql> SELECT CONCAT(RTRIM(NAME),'(',RTRIM(money),')') FROM account ORDER BY NAME;
+------------------------------------------+
| CONCAT(RTRIM(NAME),'(',RTRIM(money),')') |
+------------------------------------------+
| aaa(500) |
| NULL |
| bbb(1500) |
| ccc(1000) |
| ccc(1000) |
| ddd(13240) |
| ddd(13240) |
| t57L(1452) |
| test(66666) |
| tsdf(14520) |
+------------------------------------------+
Trim函數:去除空格
使用別名
從前面的輸出中可以看到,SELECT語句拼接地址欄位工作得很好,但此新計算列的名字是什麼呢?實際上他沒有名字,他只是一個值,如果僅在SQL查詢工具查看一下結果,這樣沒有什麼不好,但是,一個未命名的列不能用於客戶機應用中,因為客戶機沒有辦法引用他。
解決辦法是,使用別名(alias),別名是一個欄位或者的替換名
輸入: SELECT CONCAT(RTRIM(NAME), '(',RTRIM(money),')') AS vend_title FROM account ORDER BY NAME;
分析: 他指示SQL創建一個包含指定計算的名為vend_title的計算欄位
執行算數計算
輸入:
SELECT prod_id,
quantity,
item_price,
quantity*item_price AS expanded_price
FROM orderitems
WHERE order_num = 20005;