查看
- 選擇數據庫
輸入 | 輸出 |
---|---|
USE crashcourse(數據庫名); | 不返回任何結果 |
- 瞭解數據庫和表
輸入 | 輸出 |
---|---|
SHOW DATABASES; | 返回可用數據庫列表 |
SHOW TABLES; | 返回當前選擇的數據庫內可用表的列表 |
SHOW COLUMNS FROM customers(表名); | 返回表的字段,每個字段一行 |
DESCRIBE customers(表名); | 同上 |
SHOW STATUS; | 顯示廣泛的服務器狀態信息 |
SHOW CREATE DATABASE; | 顯示創建特定數據庫的MySQL語句 |
SHOW CREATE TABLE; | 顯示創建特定表的MySQL語句 |
SHOW GRANTS; | 顯示授予用戶(所有用戶或特定用戶)的安全權限 |
SHOW ERRORS; | 顯示服務器錯誤消息 |
SHOW WARNINGS; | 顯示服務器警告消息 |
HELP SHOW | 顯示允許的SHOW語句 |
檢索數據
- 檢索單列
SELECT prod_name(列名) FROM products(表名);
如果沒有明確排序查詢結果,則返回的數據的順序沒有特殊意義。
- 檢索多列
SELECT prod_id,prod_name,prod_price(列名) FROM products(表名);
SQL一般返回原始的、無格式的數據。數據的格式化是一個表示問題,而不是一個檢索問題。表示一般在顯示該數據的應用程序中規定。
- 檢索所有列
SELECT * FROM products(表名);
檢索不需要的列通常會降低檢索和應用程序的性能。
- 檢索不同的行
SELECT DISTINCT vend_id FROM products;
SELECT DISTINCT vend_id, prod_price FROM products;
DINSTICT 關鍵字應用於所有列。
- 限制結果
SELECT prod_name FROM products LIMIT 5;
SELECT prod_name FROM products LIMIT 3,4;
SELECT prod_name FROM products LIMIT 4 OFFSET 3;
檢索出來的第一行爲行0。
LIMIT指定的行數爲檢索的最大行數,行數不夠時將只返回它能返回的那麼多行。
OFFSET指定開始返回的行。
後兩句語句返回結果一樣。
- 使用完全限定的表名
SELECT products.prod_name FROM crashcourse.products;
排序檢索數據
- 按單列排序
SELECT prod_name FROM products ORDER BY prod_name; - 按多列排序
SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price, prod_name;
先按prod_price排序,當prod_price有多個行具有相同值時,再按prod_name排序。
- 指定排序方向
SELECT prod_id, prod_price,prod_name FROM products ORDER BY prod_price DESC,prod_name;
DESC只應用到直接位於其前面的列名。
升序ASC,但升序是默認的。
大小寫如何排序,取決於數據庫的設置。
ORDER BY 子句必須在FROM子句之後,LIMIT必須在ODER BY之後。
過濾數據
- WHERE子句指定搜索條件(也稱爲過濾條件)
SELECT prod_name, prod_price FROM products WHERE *prod_price = 2.50;
ORDER BY 子句應在WHERE子句之後。
數據也可以在應用層過濾。
讓客戶機應用(或開發語言)處理數據庫的工作將會極大地影響應用的性能,並且使所創建的應用完全不具備可伸縮性。
如果在客戶機上過濾數據,服務器不得不通過網絡發送多餘的數據,這將導致網絡帶寬的浪費。
- WHERE子句操作符
操作符 | 說明 |
---|---|
= | 等於 |
<> | 不等於 |
!= | 不等於 |
< | 小於 |
<= | 小於等於 |
> | 大於 |
>= | 大於等於 |
BETWEEN | 在指定的兩個值之間 |
SELECT prod_name, prod_price FROM products WHERE prod_name = ‘fuse’;
SELECT prod_name, prod_price FROM products WHERE prod_price < 10;
SELECT vend_id, prod_name FROM products WHERE vend_id <> 1003;
SELECT prod_name, prod_price FROM products WHERE prod_price BETWEEN 5 AND 10;
SELECT prod_name, prod_price FROM products WHERE prod_price IS NULL;
MySQL在執行匹配時默認不區分大小寫。
單引號用來限定字符串。
BETWEEN匹配範圍中所有的值,包括指定的開始值和結束值。
因爲NULL未知具有特殊的含義,數據庫不知道它們是否匹配,所以在匹配過濾或不匹配過濾時不返回它們。
- 組合WHERE子句(AND /OR)
SELECT prod_id,prod_name,prod_price FROM products WHERE vend_id = 1003 AND prod_price <= 10;
SELECT prod_id,prod_name,prod_price FROM products WHERE vend_id = 1003 OR vend_id = 1002;
SELECT prod_id,prod_name,prod_price FROM products WHERE (vend_id = 1003 OR vend_id = 1002) AND prod_price >= 10 ;
使用圓括號明確地分組相應的操作符。
SELECT prod_id,prod_name,prod_price FROM products WHERE vend_id IN (1002,1003) ORDER BY prod_name;
使用長的合法選項清單時,IN操作符的語法更清楚且更直觀。
使用IN時,計算的次序更容易管理。
IN操作符一般比OR操作符清單執行更快。
IN的最大優點是可以包含其他SELECT語句,使得能夠更動態地建立WHERE子句。
SELECT prod_id,prod_name,prod_price FROM products WHERE vend_id NOT IN (1002,1003)ORDER BY prod_name;
MySQL支持使用NOT對IN/BETWEEN/EXISTS子句取反。
用通配符進行過濾
利用通配符可以創建比較特定數據的搜索模式。
在搜索子句中使用通配符,必須使用LIKE操作符。
- 通配符
- 百分號 % (表示任何字符出現任意次數)
SELECT prod_id, prod_name FROM products WHERE prod_name LIKE ‘jet%’;
SELECT prod_id, prod_name FROM products WHERE prod_name LIKE ‘%anvil%’;
%能匹配0個字符。
%不能匹配NULL。
- 下劃線 _ (匹配單個字符)
SELECT prod_id, prod_name FROM products WHERE prod_name LIKE ‘_ ton anvil’;
通配符搜索的處理一般要比前面討論的其他搜索所花時間更長。
不要過度使用通配符。
在確實需要使用通配符時,除非絕對有必要,否則不能把它們用在搜索模式的開始處。
仔細注意通配符的位置。
用正則表達式進行搜索
正則表達式是用來匹配文本的特殊的串(字符集合)。
MySQL僅支持多數正則表達式實現的一個很小的子集。
關鍵字: REGEXP
LIKE與REGEXP的區別:
LIKE匹配整個列
REGEXP在列值內進行匹配
MySQL中的正則表達式匹配不區分大小寫。爲區分大小寫,可使用BINARY關鍵字。
- 基本字符匹配
SELECT prod_name FROM products WHERE prod_name REGEXP ‘1000’;
SELECT prod_name FROM products WHERE prod_name REGEXP ‘.000’; - OR匹配
SELECT prod_name FROM products WHERE prod_name REGEXP ‘1000|2000’; - 匹配幾個字符之一
SELECT prod_name FROM products WHERE prod_name REGEXP ‘[123] Ton’;
SELECT prod_name FROM products WHERE prod_name REGEXP ‘[1|2|3] Ton’;
SELECT prod_name FROM products WHERE prod_name REGEXP ‘[^123] Ton’;
SELECT prod_name FROM products WHERE prod_name REGEXP ‘1|2|3 Ton’;與SELECT prod_name FROM products WHERE prod_name REGEXP ‘[1|2|3] Ton’;結果不一樣,前者搜索的是’1’或’2’或‘3 Ton’。
- 匹配範圍
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[1-5] Ton’;
±-------------+
| prod_name |
±-------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
±-------------+ - 匹配特殊字符(轉義字符)
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘\\.’;
±-------------+
| prod_name |
±-------------+
| .5 ton anvil |
±-------------+
元字符 | 說明 |
---|---|
\\f | 換頁 |
\\n | 換行 |
\\r | 回車 |
\\t | 製表 |
\\v | 縱向製表 |
爲了匹配反斜槓(\)字符本省,需要使用\\\。
- 匹配字符類
類 | 說明 |
---|---|
[:alnum:] | 任意字母和數字,同[a-zA-Z0-9] |
[:alpha:] | 任意字符,同[a-zA-Z] |
[:blank:] | 空格和製表,同\\t |
[:cntrl:] | ASCII控制字符,ASCII 0到31和127 |
[:digit:] | 任意數字,同[0-9] |
[:graph:] | 與[:print:]相同,但不包括空格 |
[:lower:] | 任意小寫字母,同[a-z] |
[:print:] | 任意可打印字符 |
[:punct:] | 既不在[:alnum:]又不在[:cntrl:]中的任意字符 |
[:space:] | 包括空格在內的任意空白字符,同[\\f\\n\\r\\t\\v] |
[:upper:] | 任意大寫字母,同[A-Z] |
[:xdigit:] | 任意十六進制數字,同[a-fA-F0-9] |
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[:digit:]’;
±---------------+
| prod_name |
±---------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| JetPack 1000 |
| JetPack 2000 |
| TNT (1 stick) |
| TNT (5 sticks) |
±---------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[:blank:]’;
±---------------+
| prod_name |
±---------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Bird seed |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
| TNT (1 stick) |
| TNT (5 sticks) |
±---------------+
- 匹配多個實例
元字符 | 說明(匹配該元字符前面的單個字符出現的次數) |
---|---|
* | 0個或多個匹配 |
+ | 1個或多個匹配,同{1,} |
? | 0個或1個匹配,同{0,1} |
{n} | 指定數目的匹配 |
{n,} | 不少於指定數目的匹配 |
{n,m} | 匹配數目的範圍(m不超過255) |
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘\\(* sticks\)’;
±---------------+
| prod_name |
±---------------+
| TNT (5 sticks) |
±---------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘\\(* sticks+\)’;
±---------------+
| prod_name |
±---------------+
| TNT (5 sticks) |
±---------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘\\([0-9] sticks?\)’;
±---------------+
| prod_name |
±---------------+
| TNT (1 stick) |
| TNT (5 sticks) |
±---------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[[:digit:]]{4}’;
±-------------+
| prod_name |
±-------------+
| JetPack 1000 |
| JetPack 2000 |
±-------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[0-1]{4}’;
±-------------+
| prod_name |
±-------------+
| JetPack 1000 |
±-------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[0-1]{3,4}’;
±-------------+
| prod_name |
±-------------+
| JetPack 1000 |
| JetPack 2000 |
±-------------+
- 定位符
定位元字符 | 說明 |
---|---|
^ | 文本的開始 |
$ | 文本的結尾 |
[[:<:]] | 詞的開始 |
[[:>:]] | 詞的結尾 |
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘^[0-9\.]’;
±-------------+
| prod_name |
±-------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
±-------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[0]$’;
±-------------+
| prod_name |
±-------------+
| JetPack 1000 |
| JetPack 2000 |
±-------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[[j:<:]]’;
±-------------+
| prod_name |
±-------------+
| JetPack 1000 |
| JetPack 2000 |
±-------------+
mysql> SELECT prod_name FROM products WHERE prod_name REGEXP ‘[[k:>:]]’;
±---------------+
| prod_name |
±---------------+
| JetPack 1000 |
| JetPack 2000 |
| TNT (1 stick) |
| TNT (5 sticks) |
±---------------+
詞的開始和結尾的語句不是太確定,搜索以k結尾的單詞得到了“sticks”,正確用法還有待研究。
創建計算字段
直接從數據庫中檢索出轉換、計算或格式化過的數據,計算字段並不實際存在於數據庫表中。只有數據庫知道SELECT語句中哪些列是實際的表列,哪些列是計算字段。
- 拼接字段
拼接(concatenate)——函數將值聯結到一起構成單個值。
使用函數: - Concat() 拼接串
- RTrim() 去掉值右邊的所有空格
- LTrim() 去掉值左邊的所有空格
- Trim() 去掉串左右兩邊的空格
mysql> SELECT Concat(RTrim(vend_name), ‘(’, RTrim(vend_country), ‘)’) FROM vendors ORDER BY vend_name;
±--------------------------------------------------------+
| Concat(RTrim(vend_name), ‘(’, RTrim(vend_country), ‘)’) |
±--------------------------------------------------------+
| ACME(USA) |
| Anvils R Us(USA) |
| Furball Inc.(USA) |
| Jet Set(England) |
| Jouets Et Ours(France) |
| LT Supplies(USA) |
±--------------------------------------------------------+ - 使用別名——關鍵字 AS
mysql> SELECT Concat(RTrim(vend_name), ‘(’, RTrim(vend_country), ‘)’) AS vend_title FROM vendors ORDER BY vend_name;
±-----------------------+
| vend_title |
±-----------------------+
| ACME(USA) |
| Anvils R Us(USA) |
| Furball Inc.(USA) |
| Jet Set(England) |
| Jouets Et Ours(France) |
| LT Supplies(USA) |
±-----------------------+ - 執行算術計算——使用操作符 + - * /
mysql> SELECT prod_id, quantity, item_price, quantity*item_price AS expanded_price FROM orderitems WHERE order_num = 20005;
±--------±---------±-----------±---------------+
| prod_id | quantity | item_price | expanded_price |
±--------±---------±-----------±---------------+
| ANV01 | 10 | 5.99 | 59.90 |
| ANV02 | 3 | 9.99 | 29.97 |
| TNT2 | 5 | 10.00 | 50.00 |
| FB | 1 | 10.00 | 10.00 |
±--------±---------±-----------±---------------+
使用數據處理函數
函數沒有SQL的可移植性強。
- 文本處理函數
函數 | 說明 |
---|---|
Left()返回串左邊的字符 | |
Length() | 返回串的長度 |
Locate() | 找出串的一個子串 |
Lower() | 將串轉換爲小寫 |
LTrim() | 去掉串左邊的空格 |
Right() | 返回串右邊的字符 |
RTrim() | 去掉串右邊的空格 |
Soudex() | 返回串的SOUNDEX值(將文本串轉換爲描述其語音表示的字母數字模式的算法) |
SubString() | 返回子串的字符 |
Upper() | 將串轉換爲大寫 |
mysql> SELECT Left(‘help_hello’,4);
±---------------------+
| left(‘help_hello’,4) |
±---------------------+
| help |
±---------------------+
mysql> SELECT Length(vend_name) FROM vendors;
±------------------+
| length(vend_name) |
±------------------+
| 11 |
| 11 |
| 4 |
| 12 |
| 7 |
| 14 |
±------------------+
mysql> SELECT vend_name, Locate(‘s’, vend_name) FROM vendors;
±---------------±-----------------------+
| vend_name | Locate(‘s’, vend_name) |
±---------------±-----------------------+
| Anvils R Us | 6 |
| LT Supplies | 4 |
| ACME | 0 |
| Furball Inc. | 0 |
| Jet Set | 5 |
| Jouets Et Ours | 6 |
±---------------±-----------------------+
Locate()返回的是子串第一次出現的位置,字符位置從1開始計算。
mysql> SELECT vend_name, SubString(vend_name,5) FROM vendors;
±---------------±-----------------------+
| vend_name | SubString(vend_name,5) |
±---------------±-----------------------+
| Anvils R Us | ls R Us |
| LT Supplies | upplies |
| ACME | |
| Furball Inc. | all Inc. |
| Jet Set | Set |
| Jouets Et Ours | ts Et Ours |
±---------------±-----------------------+
mysql> SELECT Lower(vend_name), Upper(vend_country) FROM vendors;
±-----------------±--------------------+
| Lower(vend_name) | Upper(vend_country) |
±-----------------±--------------------+
| anvils r us | USA |
| lt supplies | USA |
| acme | USA |
| furball inc. | USA |
| jet set | ENGLAND |
| jouets et ours | FRANCE |
±-----------------±--------------------+
mysql> SELECT cust_name, cust_contact FROM customers WHERE Soundex(cust_contact) = Soundex(‘Y. Lie’);
±------------±-------------+
| cust_name | cust_contact |
±------------±-------------+
| Coyote Inc. | Y Lee |
±------------±-------------+
- 日期和時間處理函數
一般,應用程序不使用用來存儲日期和時間的格式,因此日期和時間函數總是被用來讀取、統計和處理這些值。
函數 | 說明 |
---|---|
AddData() | 增加日期計算(天、周等) |
AddTime() | 增加時間計算(時、分等) |
CurDate() | 返回當前日期 |
CurTime() | 返回當前時間 |
Data() | 返回日期時間的日期部分 |
DataDiff() | 計算兩個日期只差 |
Data_Add() | 高度靈活的日期計算函數 |
Date_Format()) | 返回一個格式化的日期或時間串 |
Day() | 返回一個日期的天數部分 |
DayOfWeek() | 對於一個日期,返回對應的星期幾 |
Hour() | 返回一個時間的小時部分 |
Minute() | 返回一個時間的分鐘部分 |
Month() | 返回一個日期的月份部分 |
Now() | 返回當前日期和時間 |
Second() | 返回一個時間的秒部分 |
Time() | 返回一個日期時間的時間部分 |
Year() | 返回一個日期的年份部分 |
mysql> select AddDate(‘2018-11-11’, INTERVAL 4 WEEK);
±---------------------------------------+
| AddDate(‘2018-11-11’, INTERVAL 4 WEEK) |
±---------------------------------------+
| 2018-12-09 |
±---------------------------------------+
mysql> select AddDate(‘2018-11-11’, INTERVAL 32 DAY);
±---------------------------------------+
| AddDate(‘2018-11-11’, INTERVAL 32 DAY) |
±---------------------------------------+
| 2018-12-13 |
±---------------------------------------+
mysql> select AddDate(‘2018-11-11’, INTERVAL 3 MONTH);
±----------------------------------------+
| AddDate(‘2018-11-11’, INTERVAL 3 MONTH) |
±----------------------------------------+
| 2019-02-11 |
±----------------------------------------+
日期格式yyyy-mm-dd
mysql> SELECT AddTime(‘23:59:59.999999’, ‘1:1:1.000002’);
±-------------------------------------------+
| AddTime(‘23:59:59.999999’, ‘1:1:1.000002’) |
±-------------------------------------------+
| 25:01:01.000001 |
±-------------------------------------------+
mysql> SELECT AddTime(‘01:59:59.999999’, ‘1:1:1.000002’);
±-------------------------------------------+
| AddTime(‘01:59:59.999999’, ‘1:1:1.000002’) |
±-------------------------------------------+
| 03:01:01.000001 |
±-------------------------------------------+
時間格式hh:mm:ss.ffffff
下面的計算結果超出了24小時:
mysql> SELECT AddTime(‘23:59:59.999999’, ‘1:1:1.000002’);
±-------------------------------------------+
| AddTime(‘23:59:59.999999’, ‘1:1:1.000002’) |
±-------------------------------------------+
| 25:01:01.000001 |
±-------------------------------------------+
mysql> SELECT CurDate();
±-----------+
| CurDate() |
±-----------+
| 2018-11-08 |
±-----------+
mysql> SELECT CurTime();
±----------+
| CurTime() |
±----------+
| 11:11:10 |
±----------+
mysql> SELECT Date(Now());
±------------+
| Date(Now()) |
±------------+
| 2018-11-08 |
±------------+
mysql> SELECT Day(CurDate());
±---------------+
| Day(CurDate()) |
±---------------+
| 8 |
±---------------+
mysql> SELECT Week(CurDate());
±----------------+
| Week(CurDate()) |
±----------------+
| 44 |
±----------------+
mysql> SELECT DayOfWeek(CurDate());
±---------------------+
| DayOfWeek(CurDate()) |
±---------------------+
| 5 |
±---------------------+
mysql> SELECT Month(CurDate());
±-----------------+
| Month(CurDate()) |
±-----------------+
| 11 |
±-----------------+
mysql> SELECT Year(CurDate());
±----------------+
| Year(CurDate()) |
±----------------+
| 2018 |
±----------------+
mysql> SELECT Time(Now());
±------------+
| Time(Now()) |
±------------+
| 11:15:41 |
±------------+
mysql> SELECT Second(CurTime());
±------------------+
| Second(CurTime()) |
±------------------+
| 41 |
±------------------+
mysql> SELECT Minute(CurTime());
±------------------+
| Minute(CurTime()) |
±------------------+
| 17 |
±------------------+
mysql> SELECT Hour(CurTime());
±----------------+
| Hour(CurTime()) |
±----------------+
| 11 |
±----------------+
mysql> SELECT DateDiff(CurDate(), ‘2017-11-11’);
±----------------------------------+
| DateDiff(CurDate(), ‘2017-11-11’) |
±----------------------------------+
| 362 |
±----------------------------------+
mysql> SELECT DateDiff(CurDate(), ‘2020-11-11’);
±----------------------------------+
| DateDiff(CurDate(), ‘2020-11-11’) |
±----------------------------------+
| -734 |
±----------------------------------+
mysql> SELECT Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1’ WEEK);
±--------------------------------------------------+
| Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1’ WEEK) |
±--------------------------------------------------+
| 2012-01-07 23:59:59 |
±--------------------------------------------------+
mysql> SELECT Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1’ YEAR);
±--------------------------------------------------+
| Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1’ YEAR) |
±--------------------------------------------------+
| 2012-12-31 23:59:59 |
±--------------------------------------------------+
mysql> SELECT Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1’ SECOND);
±----------------------------------------------------+
| Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1’ SECOND) |
±----------------------------------------------------+
| 2012-01-01 00:00:00 |
±----------------------------------------------------+
mysql> SELECT Date_Add(‘2011-12-31 23:59:59.999999’,INTERVAL ‘1’ MICROSECOND);
±----------------------------------------------------------------+
| Date_Add(‘2011-12-31 23:59:59.999999’,INTERVAL ‘1’ MICROSECOND) |
±----------------------------------------------------------------+
| 2012-01-01 00:00:00 |
±----------------------------------------------------------------+
mysql> SELECT Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1 00:00:01’ DAY_SECOND);
±-----------------------------------------------------------------+
| Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1 00:00:01’ DAY_SECOND) |
±-----------------------------------------------------------------+
| 2012-01-02 00:00:00 |
±-----------------------------------------------------------------+
mysql> SELECT Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1.000002’ SECOND_MICROSECOND);
±-----------------------------------------------------------------------+
| Date_Add(‘2011-12-31 23:59:59’,INTERVAL ‘1.000002’ SECOND_MICROSECOND) |
±-----------------------------------------------------------------------+
| 2012-01-01 00:00:00.000002 |
±-----------------------------------------------------------------------+
mysql> SELECT Date_Add(‘2011-12-31 23:59:59.000000’,INTERVAL ‘11 1:1:1:000001’ DAY_MICROSECOND);
±----------------------------------------------------------------------------------+
| Date_Add(‘2011-12-31 23:59:59.000000’,INTERVAL ‘11 1:1:1:000001’ DAY_MICROSECOND) |
±----------------------------------------------------------------------------------+
| 2012-01-12 01:01:00.000001 |
±----------------------------------------------------------------------------------+
mysql> SELECT Date_Format(Now(), ‘%d %M %Y %W %H:%I:%s’);
±-------------------------------------------+
| Date_Format(Now(), ‘%d %M %Y %W %H:%I:%s’) |
±-------------------------------------------+
| 08 November 2018 Thursday 11:11:38 |
±-------------------------------------------+
mysql> SELECT Date_Format(Now(), ‘%d %M %Y %H:%i:%s’);
±----------------------------------------+
| Date_Format(Now(), ‘%d %M %Y %H:%i:%s’) |
±----------------------------------------+
| 08 November 2018 11:33:56 |
±----------------------------------------+
更多的日期、時間串的格式見
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format
mysql> SELECT cust_id, order_num FROM orders WHERE Year(order_date) = 2005 AND Month(order_date) = 9;
±--------±----------+
| cust_id | order_num |
±--------±----------+
| 10001 | 20005 |
| 10003 | 20006 |
| 10004 | 20007 |
±--------±----------+
mysql> SELECT cust_id, order_num FROM orders WHERE Date(order_date) BETWEEN ‘2005-09-01’ AND ‘2005-09-30’;
±--------±----------+
| cust_id | order_num |
±--------±----------+
| 10001 | 20005 |
| 10003 | 20006 |
| 10004 | 20007 |
±--------±----------+
- 數值處理函數
主要用於代數、三角或幾何運算的函數。
在主要的DBMS函數中,數值函數是最一致最統一的函數。
Abs() | 返回一個數的絕對值 |
Cos() | 返回一個角度的餘弦 |
Exp() | 返回一個數的指數值 |
Mod() | 返回除操作的餘數 |
Pi() | 返回圓周率 |
Rand() | 返回一個隨機數 |
Sin() | 返回一個角度的正弦 |
Sqrt() | 返回一個數的平方根 |
Tan() | 返回一個角度的正切 |
三角函數的輸入參數爲弧度制。
mysql> SELECT Cos(PI());
±----------+
| Cos(PI()) |
±----------+
| -1 |
±----------+
mysql> SELECT Sin(PI()/2);
±------------+
| Sin(PI()/2) |
±------------+
| 1 |
±------------+
mysql> SELECT Mod(23,3);
±----------+
| Mod(23,3) |
±----------+
| 2 |
±----------+
mysql> SELECT Sqrt(16);
±---------+
| Sqrt(16) |
±---------+
| 4 |
±---------+
mysql> SELECT Tan(PI()/4);
±-------------------+
| Tan(PI()/4) |
±-------------------+
| 0.9999999999999999 |
±-------------------+
彙總數據
-
聚集函數(aggregate function)
對錶中數據進行彙總而不是把它們實際檢索出來,包括: -
確定表中行數(或者滿足某個條件或包含某個特定值的行數);
-
獲得表中行組的和;
-
找出表列(或所有行或某些特定的行)的最大值、最小值和平均值。
函數 | 說明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行數 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
mysql> SELECT AVG(prod_price) AS avg_price FROM products WHERE vend_id = 1003;
±----------+
| avg_price |
±----------+
| 13.212857 |
±----------+
AVG()只能用來確定特定數值列的平均值,而且列名必須作爲函數參數給出。
AVG()忽略NULL值。
mysql> SELECT COUNT(*) AS num_cust FROM customers;
±---------+
| num_cust |
±---------+
| 5 |
±---------+
mysql> SELECT COUNT(cust_email) AS num_emial FROM customers;
±----------+
| num_emial |
±----------+
| 3 |
±----------+
如果指定列名,則值爲NULL的行被忽略。
如果參數爲*,則不忽略NULL值。
mysql> SELECT MAX(prod_price) AS max_price FROM products;
±----------+
| max_price |
±----------+
| 55.00 |
±----------+
mysql> SELECT MIN(prod_price) AS max_price FROM products;
±----------+
| max_price |
±----------+
| 2.50 |
±----------+
MAX(),MIN()一般用來找出最大/最小的數值或日期值。
當MAX(),MIN()用於文本數據時,如果數據按相應的列排序,則MAX()返回最後一行,MIN()返回最前面一行。
MAX(),MIN()忽略NULL值。
mysql> SELECT SUM(item_price*quantity) AS total_price FROM orderitems WHERE order_num = 20005;
±------------+
| total_price |
±------------+
| 149.87 |
±------------+
SUM()忽略NULL值。
- 聚集不同值
- 對所有的行執行計算,指定ALL參數或不給參數;
- 只包含不同的值,指定DINSTINCT參數。
mysql> SELECT AVG(DISTINCT prod_price) AS avg_price FROM products WHERE vend_id = 1003;
±----------+
| avg_price |
±----------+
| 15.998000 |
±----------+
mysql> SELECT AVG(prod_price) AS avg_price FROM products WHERE vend_id = 1003;
±----------+
| avg_price |
±----------+
| 13.212857 |
±----------+
DISTINCT必須使用列名,不能用於計算或表達式。
- 組合聚集函數
將多個聚集函數用於單條SELECT語句。
mysql> SELECT COUNT(*) AS num_items,
-> MIN(prod_price) AS min_price,
-> MAX(prod_price) AS max_price,
-> AVG(prod_price) AS avg_price
-> FROM products;
±----------±----------±----------±----------+
| num_items | min_price | max_price | avg_price |
±----------±----------±----------±----------+
| 14 | 2.50 | 55.00 | 16.133571 |
±----------±----------±----------±----------+
分組數據
分組允許把數據分爲多個邏輯組,以便能對每個組進行聚集計算。
- 創建分組
mysql> SELECT vend_id, COUNT(*) AS num_prods FROM products GROUP BY vend_id;
±--------±----------+
| vend_id | num_prods |
±--------±----------+
| 1001 | 3 |
| 1002 | 2 |
| 1003 | 7 |
| 1005 | 2 |
±--------±----------+
GROUP BY可以包含任意數目的列,這使得能對分組進行嵌套,爲數據分組提供更細緻的控制。
如果在GROUP BY子句中嵌套了分組,數據將在最後規定的分組上進行彙總。(在建立分組時,指定的所有列都一起計算)
GROUP BY子句中列出的每個列都必須是檢索列或有效的表達式(但不能是聚集函數)。如果在SELECT中使用表達式,則必須在GROUP BY子句中指定相同的表達式。不能使用別名。
除聚集計算語句外,SELECT語句中的每個列都必須在GROUP BY子句中給出。
如果分組列中有NULL值,則NULL作爲一個分組返回。如果列中有多行NULL值,它們將分爲一組。
GRUOP BY子句必須出現在WHERE子句之後,ORDER BY子句之前。
使用關鍵字WITH ROLLUP可以得到每個分組以及每個分組彙總級別(針對每個分組)的值。
mysql> SELECT vend_id, COUNT(*) AS num_prods FROM products GROUP BY vend_id WITH ROLLUP;
±--------±----------+
| vend_id | num_prods |
±--------±----------+
| 1001 | 3 |
| 1002 | 2 |
| 1003 | 7 |
| 1005 | 2 |
| NULL | 14 |
±--------±----------+
- 過濾分組
WHERE過濾的是行,使用HAVING過濾分組。
HAVING支持所有WHERE操作符。
mysql> SELECT cust_id, COUNT() AS orders FROM orders GROUP BY cust_id HAVING COUNT() >= 2;
±--------±-------+
| cust_id | orders |
±--------±-------+
| 10001 | 2 |
±--------±-------+
WHERE在分組前過濾,HAVING在分組後進行過濾。
WHERE排除的行不包括在分組中。
mysql> SELECT vend_id, COUNT() AS num_prods FROM products WHERE prod_price >= 10 GROUP BY vend_id HAVING COUNT() >= 2;
±--------±----------+
| vend_id | num_prods |
±--------±----------+
| 1003 | 4 |
| 1005 | 2 |
±--------±----------+
mysql> SELECT vend_id, COUNT() AS num_prods FROM products GROUP BY vend_id HAVING COUNT() >= 2;
±--------±----------+
| vend_id | num_prods |
±--------±----------+
| 1001 | 3 |
| 1002 | 2 |
| 1003 | 7 |
| 1005 | 2 |
±--------±----------+
- 分組和排序
一般在使用GROUP BY子句時,應該也給出ORDER BY 子句,這是保證數據正確排序的唯一方法。千萬不要依賴GROUP BY排序數據。
mysql> SELECT order_num, SUM(quantityitem_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING SUM(quantityitem_price) >= 50 ORDER BY ordertotal;
±----------±-----------+
| order_num | ordertotal |
±----------±-----------+
| 20006 | 55.00 |
| 20008 | 125.00 |
| 20005 | 149.87 |
| 20007 | 1000.00 |
±----------±-----------+
順序
SELECT – FROM – WHERE – GROUP BY – HAVING – ORDER BY – LIMIT
子查詢
子查詢:嵌套在其他查詢中的查詢。
- 利用子查詢進行過濾
mysql> 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 = ‘TNT2’));
±---------------±-------------+
| cust_name | cust_contact |
±---------------±-------------+
| Coyote Inc. | Y Lee |
| Yosemite Place | Y Sam |
±---------------±-------------+
對於能嵌套的子查詢的數目沒有限制,不過在實際使用時由於性能的限制,不能嵌套太多的子查詢。
在WHERE子句中使用子查詢,應該保證SELECT語句具有與WHERE子句相同數目的列。
子查詢一般與IN操作符結合使用,也可以用於測試 等於= 不等於<> 等。
- 作爲計算字段使用子查詢
mysql> SELECT cust_name, cust_state,
-> (SELECT COUNT(*) FROM orders
-> WHERE orders.cust_id = customers.cust_id) AS orders
-> FROM customers
-> ORDER BY cust_name;
±---------------±-----------±-------+
| cust_name | cust_state | orders |
±---------------±-----------±-------+
| Coyote Inc. | MI | 2 |
| E Fudd | IL | 1 |
| Mouse House | OH | 0 |
| Wascals | IN | 1 |
| Yosemite Place | AZ | 1 |
±---------------±-----------±-------+