《MySQL必知必會》學習筆記-使用MySQL查詢數據

查看

  • 選擇數據庫
輸入 輸出
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 |
    ±---------------±-----------±-------+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章