MySQL 学习笔记(3)— 字符串函数、数值函数、日期时间函数、流程函数、聚集函数以及分组数据
1. 字符串函數
MySQL 的常用函數包括字符串函數、數值函數、日期時間函數、流程函數等。
SELECT ascii("abc"),char(97),concat("hello", "world"),lower("HELLO,WORLD"),char_length("hello"),octet_length("hello"),substring("hello", 1, 3),instr("hello", "el"),replace("hello", 'l', 'b'),trim("o" from "hello"),trim(" hello "),upper("hello");
結果:
各數據庫支持常見的字符串函數
| 函數 | 描述 | Oracle | MySQL | SQL Server | PostgreSQL |
|---|---|---|---|---|---|
| ASCII(str) | 返回第一個字符的 ASCII 編碼 | 支持 | 支持 | 支持 | 支持 |
| CHR(n) / CHAR(n) | 返回 ASCII 編碼 n 對應的字符 | CHR(n) | CHAR(n) | CHAR(n) | CHR(n) |
| CONCAT(str1, str2, …) | 拼接字符串 | 支持 | 支持 | 支持 | 支持 |
| LOWER(str) | 返回字符串的小寫形式 | 支持 | 支持 | 支持 | 支持 |
| CHAR_LENGTH(str) | 返回字符數量 | LENGTH(str) | 支持 | LEN(str) | 支持 |
| OCTET_LENGTH(str) | 返回字節數量 | LENGTHB(str) | 支持 | DATALENGTH(str) | 支持 |
| SUBSTRING(str, n, m) | 返回字符串從位置 n 開始的 m 個字符 | SUBSTR(str, n, m) | 支持 | 支持 | 支持 |
| INSTR(str, sub) | 返回 str 中首次出現 sub 的位置 | 支持 | 支持 | PATINDEX( ‘%pattern%’, str) | POSITION(sub IN str) |
| REPLACE(str, old, new) | 將字符串中的 old 子串替換為 new 子串 | 支持 | 支持 | 支持 | 支持 |
| TRIM(sub FROM str) | 刪除字符串開頭和結尾的 sub 字串 | 支持 | 支持 | 支持 | 支持 |
| UPPER(str) | 返回字符串額大寫形式 | 支持 | 支持 | 支持 | 支持 |
2. 數值函數
SELECT abs(-2),ceil(3.4),floor(3.4),mod(10, 2),rand(),round(3.6, 4),truncate(3.1415926, 4);
輸出結果:
以下是 SQL 中常見的數值函數及不同數據庫中的實現:
來源: https://gitbook.cn/gitchat/column/5dae96ec669f843a1a4aed95/topic/5db7cdcef6a6211cb96197b6
| 函數 | 描述 | Oracle | MySQL | SQL Server | PostgreSQL |
|---|---|---|---|---|---|
| ABS(x) | 計算 x 的絕對值 | 支持 | 支持 | 支持 | 支持 |
| CEIL(x) / CEILING(x) | 計算大于等于 x 的最小整數 | 支持 CEIL(x) | 支持 | 支持 CEILING(x) | 支持 |
| EXP(x) | 計算 e 的 x 次冪,e 約等于 2.71828 | 支持 | 支持 | 支持 | 支持 |
| FLOOR(x) | 計算小于等于 x 的最大整數 | 支持 | 支持 | 支持 | 支持 |
| LN(x) | 計算 x 的自然對數,底數為 e | 支持 | 支持 | LOG(x) | 支持 |
| LOG(y, x) | 計算以 y 為底的 x 的對數 | 支持 | 支持 | LOG(x, y) | 支持 |
| MOD(x, y) | 計算 x 除以 y 的余數,即求模運算 | 支持 | 支持 | x % y | 支持 |
| POWER(x, y) | 計算 x 的 y 次冪 | 支持 | 支持 | 支持 | 支持 |
| ROUND(x, y) | 將 x 四舍五入到 y 位小數 | 支持 | 支持 | 支持 | 支持 |
| SQRT(x) | 計算 x 的平方根 | 支持 | 支持 | 支持 | 支持 |
| GREAST(x, y, …) | 計算參數列表中的最大值 | 支持 | 支持 | 不支持 | 支持 |
| LEAST(x, y, …) | 計算參數列表中的最小值 | 支持 | 支持 | 不支持 | 支持 |
| RANDOM( ) | 返回一個大于等于 0 小于 1 的隨機數 | DBMS_RANDOM.VALUE | RAND() | RAND() | 支持 |
3. 日期時間函數
在數據庫中,日期時間類型存在 3 種形式:
DATE,日期類型,包含年、月、日。可以用于存儲出生日期、入職日期等。TIME,時間類型,包含時、分、秒,以及小數秒。一般使用較少。TIMESTAMP,時間戳類型,包含年、月、日、時、分、秒,以及小數秒。用于對時間精度要求比較高的場景,比如存儲訂單時間。
TIMESTAMP 和 TIME 還可以添加 WITH TIME ZONE 選項,用于指定一個時區偏移量。例如,UTC 標準時間的 0 點等于北京時間的早上 8 點。時區選項通常用于支持全球化的應用系統中。
以下是 4 種數據庫對于日期時間類型的支持情況。
| 數據類型 | Oracle | MySQL | SQL Server | PostgreSQL |
|---|---|---|---|---|
| DATE | 包含額外的時、分、秒 | 支持 | 支持 | 支持 |
| TIME | 不支持 | 支持,不支持時區 | 支持,不支持時區 | 支持,支持時區 |
| TIMESTAMP | 支持,包含時區 | 支持,使用 UTC 時區 | DATETIME2、DATETIMEOFFSET | 支持,支持時區 |
其中,Oracle 的 DATE類型包含了日期和時間兩部分,但不支持 TIME類型。MySQL 還提供了 DATETIME 日期時間類型。
下表列出了 SQL 中常見的日期時間函數:
| 函數 | 描述 | Oracle | MySQL | SQL Server | PostgreSQL |
|---|---|---|---|---|---|
| CURRENT_DATE | 獲取系統當前日期 | 支持 | 支持 | CAST(GETDATE() AS DATE) | 支持 |
| CURRENT_TIME | 獲取系統當前時間 | 支持 | 支持 | CAST(GETDATE() AS TIME) | 支持 |
| CURRENT_TIMESTAMP | 獲取系統當前日期 | 支持 | 支持 | 支持 | 支持 |
| EXTRACT(part FROM dt) | 返回日期時間中的年、月、日等 | 支持 | 支持 | DATEPART(part, dt) | 支持 |
| dt1 - dt2 | 計算兩個日期之間的天數 | 支持 | DATEDIFF(dt2, dt1) | DATEDIFF(DAY, dt1, dt2) | 支持 |
| dt + INTERVAL | 日期加上一段時間間隔 | 支持 | 支持 | DATEADD(part, n, dt) | 支持 |
SELECT curdate(),curtime(),now(),unix_timestamp(curdate()),from_unixtime(curdate()),week("2020-02-28"),year("2020-02-28"),hour("20:40:20"),minute("20:40:20"),monthname("2020-02-28"),date_format("2020-02-28", "%Y_%m_%d"),datediff("2020-02-28", "2020-02-01");
輸出結果:
除此之外,各種數據庫還提供了一些擴展的函數:
Oracle支持SYSDATE、SYSTIMESTAMP獲取當前日期和時間戳;MySQL支持CURDATE()、CURRENTDATE()獲取當前日期,CURTIME()、CURRENTTIME()獲取當前時間,NOW()、CURRENT_TIMESTAMP()獲取當前時間戳;SQL Server支持SYSDATETIME()、SYSDATETIMEOFFSET()獲取系統當前時間戳;PostgreSQL支持NOW()獲取系統當前時間戳。
EXTRACT(part FROM dt) 函數可以返回日期時間中的某個部分,例如年、月、小時等。以下示例查找 2018 年入職的員工:
-- Oracle、MySQL 以及 PostgreSQL 實現
SELECT emp_name, hire_dateFROM employeeWHERE EXTRACT(YEAR FROM hire_date) = 2018;
4. 常用函數
5. 流程函數
SQL 中的 CASE 表達式可以根據不同條件產生不同的結果,實現類似于編程語言中的 IF-THEN-ELSE 邏輯功能。
5.1 簡單 CASE 表達式
簡單 CASE 表達式的語法如下:
CASE expressionWHEN value1 THEN result1WHEN value2 THEN result2...[ELSE default_result]
END
首先計算 expression 的值;然后依次與 WHEN 列表中的值(value1,value2,…)進行比較,找到第一個相等的值并返回對應的結果(result1,result2,…);如果沒有找到相等的值,返回 ELSE 中的默認結果;如果此時沒有指定 ELSE,返回 NULL 值。
使用示例:
SELECT name, case idwhen 1 then "第一"when 2 then "第二"when 3 then "第三"else "其它的"end as order_zone
FROM zone
結果顯示:
5.2 搜索 CASE 表達式
搜索 CASE 表達式的語法如下:
CASEWHEN condition1 THEN result1WHEN condition2 THEN result2...[ELSE default_result]
END
按照順序依次計算每個分支中的條件(condition1,condition2,…),找到第一個結果為真的分支并返回相應的結果(result1,result2,…);如果沒有任何條件為真,返回 ELSE 中的默認結果;如果此時沒有指定 ELSE,返回 NULL 值。
所有的簡單 CASE 表達式都可以替換為等價的搜索 CASE 表達式。
SELECT name, case when id=1 then "第一"when id=2 then "第二"when id=3 then "第三"else "其它的"end as order_zone
FROM zone
6. 聚集函數
聚集函數包括 AVG()、COUNT()、MAX()、MIN()、SUM()。
聚集函數 COUNT、SUM、AVG、MAX、MIN 只有 COUNT 可以將 * 號作為參數,其它聚合函數都不行。
MAX、MIN 函數適用于幾乎所有的數據類型的列;而 SUM / AVG 僅適用于數值類型的列
6.1 COUNT 統計數量
COUNT(*) 函數用于統計行數。
SELECT COUNT(*) FROM product;
COUNT 函數也可以統計某個字段或者表達式的數量。
SELECT COUNT(product_type) FROM product;
使用聚合函數時需要注意兩點:
- 在聚合函數的參數中加上
DISTINCT關鍵字,可以在計算之前排除重復值; - 聚合函數在計算時,忽略輸入值為
NULL的數據行;COUNT(*)除外。
使用聚合函數刪除重復的值
SELECT COUNT(DISTINCT product_type) FROM product;
6.2 AVG 函數計算平均值
SELECT AVG(price) FROM product;
其它 SUM()/MAX()/MIN()/ 用法和 AVG() 用法類似。
7. 分組數據
分組數據主要是對過濾的數據進行分類。SQL 中的 GROUP BY 子句可以將數據按照某種規則進行分組。
GROUP BY子句中指定的列稱為聚合鍵或者分組列,SELECT子句中不能出現聚合鍵之外的列名,
SELECT product_type, COUNT(*) FROM product
GROUP BY product_type;
- 對于
GROUP BY,如果分組字段中存在多個NULL值,它們將被分為一個組。
SELECT purchase_price, COUNT(*) FROM product
GROUP BY purchase_price;
- 帶有
WHERE子句的GROUP BY語句
SELECT purchase_price, COUNT(*) FROM product WHERE product_type = "辦公用品" GROUP BY purchase_price;
為聚合結果指定條件:
WHERE子句 = 指定行 所對應的條件HAVING子句 = 指定組 所對應的條件
從性能的角度來說,應該盡量使用 WHERE 條件過濾掉更多的數據,而不是等到分組之后再使用 HAVING 進行過濾;但如果業務需求只能基于匯總之后的結果進行過濾,那就另當別論了。
在 SQL 語句中可以使用 WHERE 子句對表進行過濾,同時使用 HAVING 對分組結果進行過濾。
SELECT purchase_price, COUNT(*)
FROM product
WHERE product_type = "辦公用品"
GROUP BY purchase_price
HAVING COUNT(*) = 2;
- 對查詢結果進行排序,默認按照升序排列
ASC
SELECT product_id, product_name, sale_price, purchase_price
FROM product
ORDER BY sale_price;
指定降序排列
SELECT product_id, product_name, sale_price, regist_date
FROM product
ORDER BY sale_price DESC;
如果想要對多個列進行按序排列,則需要對多個列指定關鍵字
SELECT product_id, product_name, sale_price, regist_date
FROM product
ORDER BY sale_price DESC, regist_date ASC;
指定多個排序鍵,優先使用左側的鍵,如果該列存在相同值的話,再按照右側的鍵
SELECT product_id, product_name, sale_price, purchase_price
FROM product
ORDER BY sale_price, product_id;
排序鍵包含 NULL 時,會在開頭或者末尾進行匯總
SELECT product_id, product_name, sale_price, purchase_price
FROM product
ORDER BY purchase_price;
在 ORDER BY 子句中可以使用 SELECT 子句中未使用的列和聚合函數
SELECT product_name, sale_price, purchase_price
FROM product
ORDER BY product_id;SELECT product_type, COUNT(*)
FROM product
GROUP BY product_type
ORDER BY COUNT(*);
9. 類型轉換函數
CAST(expr AS type) 函數用于將數據轉換為不同的類型。以下是一個類型轉換的示例:
-- Oracle 實現
-- 修改日期顯示格式
ALTER SESSION SET nls_date_format = 'yyyy-mm-dd';
SELECT CAST('666' AS INTEGER), CAST(hire_date AS CHAR(10))FROM employeeWHERE emp_id = 1;-- SQL Server 和 PostgreSQL 實現
SELECT CAST('666' AS INTEGER), CAST(hire_date AS CHAR(10))FROM employeeWHERE emp_id = 1;-- MySQL 實現
SELECT CAST('666' AS SIGNED INTEGER), CAST(hire_date AS CHAR(10))FROM employeeWHERE emp_id = 1;
總結
以上是生活随笔為你收集整理的MySQL 学习笔记(3)— 字符串函数、数值函数、日期时间函数、流程函数、聚集函数以及分组数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL 学习笔记(2)— 通配符/正
- 下一篇: MySQL 学习笔记(4)— 组合查询、