mysql_複習02
select
- 基本語法:
select 查詢列 from 表名
- 常量
select 常量值1,常量值2,常量值3;
select查詢基礎篇
- 基礎語法:
select 查詢的列 from 表名 select a from text;
- 查詢常量
select 常量值1,常量值2,常量值3;
- 查詢表示式
select 表示式;
- 查詢函式
select 函式;
- 指定欄位查詢語法
select 欄位1,欄位2,欄位3 from 表名;
- 查詢所有列
select * from text;
- 列表名
- 語法;
select 列 [as] 別名 from 表;
- 表列名
select 別名.欄位,別名.*from 表名 [as] 別名;
例子:
select t.age as '年齡',t.name as '名字' from temp02 as t;
select條件查詢
- 語法;
select 列名 from 表名 where 列 運算子 值;
條件運算子
+ = 等於
+ <>或者 != 不等於
+ '>' 大於
+ < 小於
+ '>=' 大於等於
+ <= 小於等於
邏輯運算子
+ AND 多條件成立
+ OR 多個條件滿足一個
like模糊查詢
- 語法:
select 列名 from 表名 where 列 like pattern;
pattern 中可以包含萬用字元,有一下幾種萬用字元
%: 表示匹配任意一個或多個字元
_ :表示匹配任意一個字元
between and(區間查詢)
- 概念; 操作符between and(區間查詢)會選取介於兩個值之間的資料範圍,這些值可以是資料,文字或者日期,屬於一個閉區間查詢。
select 列名 from 表名 where 列名 between 值1 and 值2;
返回between和and裡面的資料,between and可以提高語句的簡潔
IN操作符
- 當查詢同一個欄位但要查詢很多資料,我們會使用or,但是or不夠簡潔
- IN操作符
- 語法: select 列名 from 表名 where 欄位 in(值1,值2,值3);
這樣會變得更加簡潔
in列表不支援萬用字元,in滿足裡面任意一個都會返回對應的值
- 例子:
select * from text t where t.age in(1,2,3,4);
not in 查詢
- 概念;not in 和 in剛好相反,in列表匹配會返回,not in是和列表不匹配才會返回.
select 列名 from 表名 where 欄位 not in (值1,值2,值3)
NULL存在的坑
- 如果資料裡面為null,那麼使用條件查詢,是查詢不到的。所以我們因該使用,NULL的專門查詢方式
- IS NULL(返回值為空的記錄)
select 列名 from 表名 where 列 is null;
指定的列的值為null的記錄
- is not NULL(返回值不為空的記錄)
select 列名 from 表名 where 列 is not null;
查詢指定的列的值不為null的記錄
<=>(安全等於)
- 功能: 既可以判斷NULL值,又可以判斷普通的數值,可讀性較低,用的少.
排序和分頁(order by,limit)
select 欄位名 from 表名 order by 欄位1 [asc|desc],欄位2 [asc|desc];
asc|desc表示排序的規則,asc:升序,desc:降序.預設asc
排序支援單欄位和多欄位排序。
也可以在where後面來排序
limit介紹
- 概念: limit用來限制select查詢返回的行數,常用來分頁等操作
- 語法:
select 列 from 表 limit [offset,] count;
說明:
offset:表四偏移量,通俗點來講就是跳過了多少行,offset可以省略,預設為0,表示跳過0行
count :跳過offset行之後開始取資料,取count行記錄;範圍:[0,+∞]
limit分頁查詢
- limit分頁查詢,使用limit來分頁
select 列 from 表名 limit (page - 1) * pageSize,pageSize;
page: 表示為第幾頁
pageSize: 表示每頁顯示多少條記錄
limit中不能使用表示式,limit後面只能跟明確的數字.limit後面數字不能為負數
- 分頁查詢的坑
- 當b欄位出現重複的值,那麼排序將會打亂,資料出現重複的值。處理方案:將兩個欄位都要進行升降排列
分頁排序時,排序不要有二義性,二義性情況下可能會導致分頁結果亂序,可以在後面追加一個主
鍵排序
分組查詢(group by,having)
- 語法:
SELECT column, group_function,... FROM table
[WHERE condition]
GROUP BY group_by_expression
[HAVING group_condition];
- 說明:
group_function:聚合函式。
group_by_expression:分組表示式,多個之間用逗號隔開。
group_condition:分組之後對資料進行過濾。
分組中,select後面只能有兩種型別的列:
- 出現在group by後的列
- 或者使用聚合函式的列
- group_function:聚合函式
- max: 指定列的最大值
- min: 查詢指定列的最小值
- count: 統計查詢結果的行數
- sum: 求和,返回指定的總和
- avg: 求平均數,返回列資料的平均值
having
- 分組後篩選資料 使用having
where & group by & having & order by & limit 一起協
作
select 列 from
表名
where [查詢條件]
group by [分組表示式]
having [分組過濾條件]
order by [排序條件]
limit [offset,] count;
必須按照上面順序來寫
mysql常用函式彙總
數值型函式
函式名稱 | 作 用 |
---|---|
abs | 求絕對值 |
sqrt | 求二次方根 |
mod | 求餘數 |
ceil 和 ceiling | 兩個函式功能相同,都是返回不小於引數的最小整數,即向上取整 |
floor | 向下取整,返回值轉化為一個BIGINT |
rand | 生成一個0~1之間的隨機數,傳入整數引數是,用來產生重複序列 |
round | 對所傳引數進行四捨五入 |
sign | 返回引數的符號 |
pow 和 power | 兩個函式的功能相同,都是所傳引數的次方的結果值 |
sin | 求正弦值 |
asin | 求反正弦值,與函式 SIN 互為反函式 |
cos | 求餘弦值 |
acos | 求反餘弦值,與函式 COS 互為反函式 |
tan | 求正切值 |
atan | 求反正切值,與函式 TAN 互為反函式 |
cot | 求餘切值 |
MySQL 字串函式
函式名稱 | 作 用 |
---|---|
length | 計算字串長度函式,返回字串的位元組長度 |
concat | 合併字串函式,返回結果為連線引數產生的字串,引數可以使一個或多個 |
insert | 替換字串函式 |
lower | 將字串中的字母轉換為小寫 |
upper | 將字串中的字母轉換為大寫 |
left | 從左側字擷取符串,返回字串左邊的若干個字元 |
right | 從右側字擷取符串,返回字串右邊的若干個字元 |
trim | 刪除字串左右兩側的空格 |
replace | 字串替換函式,返回替換後的新字串 |
substr 和substring | 擷取字串,返回從指定位置開始的指定長度的字元換 |
reverse | 字串反轉(逆序)函式,返回與原始字串順序相反的字串 |
MySQL 日期和時間函式
函式名稱 | 作 用 |
---|---|
curdate 和current_date | 兩個函式作用相同,返回當前系統的日期值 |
curtime 和current_time | 兩個函式作用相同,返回當前系統的時間值 |
now 和 sysdate | 兩個函式作用相同,返回當前系統的日期和時間值 |
unix_timestamp | 獲取UNIX時間戳函式,返回一個以 UNIX 時間戳為基礎的無符號整數 |
from_unixtime | 將 UNIX 時間戳轉換為時間格式,與UNIX_TIMESTAMP互為反函式 |
month | 獲取指定日期中的月份 |
monthname | 獲取指定日期中的月份英文名稱 |
dayname | 獲取指定曰期對應的星期幾的英文名稱 |
dayofweek | 獲取指定日期是一週中是第幾天,返回值範圍是1~7,1=週日 |
week | 獲取指定日期是一年中的第幾周,返回值的範圍是否為 0〜52 或 1〜53 |
dayofyear | 獲取指定曰期是一年中的第幾天,返回值範圍是1~366 |
dayofmonth | 獲取指定日期是一個月中是第幾天,返回值範圍是1~31 |
year | 獲取年份,返回值範圍是 1970〜2069 |
time_to_sec | 將時間引數轉換為秒數 |
sec_to_time | 將秒數轉換為時間,與TIME_TO_SEC 互為反函式 |
date_add 和 adddate | 兩個函式功能相同,都是向日期新增指定的時間間隔 |
date_sub 和 subdate | 兩個函式功能相同,都是向日期減去指定的時間間隔 |
addtime | 時間加法運算,在原始時間上新增指定的時間 |
subtime | 時間減法運算,在原始時間上減去指定的時間 |
datediff | 獲取兩個日期之間間隔,返回引數 1 減去引數 2 的值 |
date_format | 格式化指定的日期,根據引數返回指定格式的值 |
weekday | 獲取指定日期在一週內的對應的工作日索引 |
MySQL 流程控制函式
- if 判斷,流程控制
IF(expr,v1,v2)
當 expr 為真是返回 v1 的值,否則返回 v2
- ifnull 判斷是否為空
IFNULL(v1,v2):v1為空返回v2,否則返回v1.
- case 搜尋語句
類似於java中的if..else if..else
CASE <表示式>
WHEN <值1> THEN <操作>
WHEN <值2> THEN <操作>
...
ELSE <操作>
END CASE;
或者
CASE
WHEN <條件1> THEN <命令>
WHEN <條件2> THEN <命令>
...
ELSE commands
END CASE;
其他函式
函式名稱 | 作用 |
---|---|
version | 資料庫版本號 |
database | 當前資料庫 |
user | 當前連線使用者 |
password | 返回字串密碼形式 |
md5 | 返回字串md5資料 |
深入瞭解連線查詢及原理
- 但我們要查詢多個表的時候,使用連線查詢來提高查詢效率!
笛卡爾積
- 兩個集合a和b,產生的可能是a*b。(兩集合相互關聯的所有可能)
- 語法:
select 欄位 from 表1,表2[,表N];
或者
select 欄位 from 表1 join 表2 [join 表N];
內連線
select 欄位 from 表1 inner join 表2 on 連線條件;
或
select 欄位 from 表1 join 表2 on 連線條件;
或
select 欄位 from 表1, 表2 [where 關聯條件];
內連線相當於在笛卡爾積的基礎上加上了連線的條件
當沒有連線條件的時候,內連線上升為笛卡爾積。
內連線使用第三種,簡潔!
外連線
- 外連線涉及2個表,分為:主表和從表,要查詢的資訊主要來自於那個表,誰就是主表
- 外連線查詢結果為主表中所有記錄。如果從表中有和它匹配的,則顯示匹配的值,這部分相當於內連線查詢出來的結果;如果從表中沒有和它匹配的,則顯示null。
- 最終:外連線查詢結果 = 內連線的結果 + 主表中有的而內連線結果中沒有的記錄。
- 外連線分為2種:
- 左外連結:使用left join關鍵字,left join左邊的是主表。
- 右外連線:使用right join關鍵字,right join右邊的是主表。
左連線
- 語法;
select 列 from 主表 left join 從表 on 連線條件;
右連線
- 語法:
select 列 from 從表 right join 主表 on 連線條件
子查詢♥
- 簡要:出現在select語句中的select語句,稱為子查詢或內查詢
- 子查詢分類
- 標量子查詢(結果集只有一行一列)
- 列子查詢(結果集只有一列多行)
- 行子查詢(結果集有一行多列)
- 表子查詢(結果集一般為多行多列)
- select後面:僅僅支援標量子查詢。
- from後面:支援表子查詢。
- where或having後面:支援標量子查詢(單列單行)、列子查詢(單列多行)、行子查詢(多列多行)
- exists後面(即相關子查詢):表子查詢(多行、多列)
select後面的子查詢
- select 裡面還有select查詢
from後面的子查詢
- 將子查詢結果的表當作一張表,必須起別名,否則找不到表,然後將真實的表和子查詢結果的表進行連線查詢.
where和having後面的子查詢
- mysql中的in,any,some,all
- in,any,some,all分別是子查詢關鍵詞之一
- in(not in):列表中的"任意一個"
- any或者some:和子查詢返回某一個值比較,比如a>some(10,20,30),a大於子查詢中任意一個即可,等同於a>min(10,20,30)
- all:等同於 a>all(10,20,30),a大於子查詢中的所有制
NULL的坑
in和null比較
mysql> select * from test1;
+------+------+
| a | b |
+------+------+
| 1 | 1 |
| 1 | NULL |
| NULL | NULL |
+------+------+
3 rows in set (0.00 sec)
mysql> select * from test1 where a in (null);
Empty set (0.00 sec)
mysql> select * from test1 where a in (null,1);
+------+------+
| a | b |
+------+------+
| 1 | 1 |
| 1 | NULL |
+------+------+
2 rows in set (0.00 sec)
結論: 當in和null比較時,無法查詢出為null的記錄.
not in和null比較
mysql> select * from test1 where a not in (1);
Empty set (0.00 sec)
mysql> select * from test1 where a not in (null);
Empty set (0.00 sec)
mysql> select * from test1 where a not in (null,2);
Empty set (0.00 sec)
mysql> select * from test1 where a not in (2);
+------+------+
| a | b |
+------+------+
| 1 | 1 |
| 1 | NULL |
+------+------+
2 rows in set (0.00 sec)
結論:當not in後面有null值時,不論什麼情況下,整個sql查詢結果都為空.
exists,not exists和null比較
mysql> select * from test2;
+------+------+
| a | b |
+------+------+
| 1 | 1 |
| 1 | NULL |
| NULL | NULL |
+------+------+
3 rows in set (0.00 sec)
mysql> select * from test1 t1 where exists (select * from test2 t2 where t1.a =
t2.a);
+------+------+
| a | b |
+------+------+
| 1 | 1 |
| 1 | NULL |
+------+------+
2 rows in set (0.00 sec)
mysql> select * from test1 t1 where not exists (select * from test2 t2 where
t1.a = t2.a);
+------+------+
| a | b |
+------+------+
| NULL | NULL |
+------+------+
1 row in set (0.00 sec)
結論: 因為=不能比較null
聚合函式的null坑
mysql> select count(a),count(b),count(*) from test1;
+----------+----------+----------+
| count(a) | count(b) | count(*) |
+----------+----------+----------+
| 2 | 1 | 3 |
+----------+----------+----------+
1 row in set (0.00 sec)
count(a)返回了2行記錄,a欄位為NULL的沒有統計出來。
count(b)返回了1行記錄,為NULL的2行記錄沒有統計出來。
count(*)可以統計所有資料,不論欄位的資料是否為NULL。
mysql> select * from test1 where a is null;
+------+------+
| a | b |
+------+------+
| NULL | NULL |
+------+------+
1 row in set (0.00 sec)
mysql> select count(a) from test1 where a is null;
+----------+
| count(a) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
上面第1個sql使用is null查詢出了結果,第2個sql中count(a)返回的是0行。
結論:count(欄位)無法統計欄位為NULL的值,count(*)可以統計值為null的行。
NULL不能作為主鍵的值
- 但我們建立主鍵時,雖然沒有指定not null但是,使用show create table xx 會發現建立的主鍵自動變成了not null
總結
- 操作null其實很複雜,也很容易出錯,最有效的方法時避免使用null
事務詳解
- 什麼時事務?
- 資料庫中的事務是指對資料庫執行一批操作,這些操作最終要麼全部執行成功,要麼全部失敗,不會存在部分成功的情況。
舉個例子
比如A使用者給B使用者轉賬100操作,過程如下:
如果在事務的支援下,上面最終只有2種結果:
- 資料庫中的事務是指對資料庫執行一批操作,這些操作最終要麼全部執行成功,要麼全部失敗,不會存在部分成功的情況。
- 操作成功:A賬戶減少100;B賬戶增加100
1.從A賬戶扣100
2.給B賬戶加100
- 操作失敗:A、B兩個賬戶都沒有發生變化
如果沒有事務的支援,可能出現錯:A賬戶減少了100,此時系統掛了,導致B賬戶沒有加上100,而A賬戶憑空少了100。
- 事務有四種特性
- 原子性
- 一致性
- 隔離性
- 永續性
mysql中事務操作
隱式事務
- 預設是隱式事務,執行insert,updatae,delete操作的時候。
- 檢視變數autocommit是否開啟了自動提交
show variables like 'autocommit'
autocommit為NO表示開啟了自動提交
顯式事務
顯式事務需要手動開啟,提交或回滾。有開發者自己控制
- 方法一:
- 語法:
//設定不自動提交事務
set autocommit=0;
//執行事務操作
commit|rollback;
- 方法二:
- 語法:
start transaction;//開啟事務
//執行事務操作
commit|rollback;
savepoint關鍵字
- 功能可以回滾我們想要指定的回滾某個部分
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test1 values (1);
Query OK, 1 row affected (0.00 sec)
mysql> savepoint part1;//設定一個儲存點
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test1 values (2);
Query OK, 1 row affected (0.00 sec)
mysql> rollback to part1;//將savepint = part1的語句到當前語句之間所有的操作回滾
Query OK, 0 rows affected (0.00 sec)
mysql> commit;//提交事務
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
從上面可以看出,執行了2次插入操作,最後只插入了1條資料。
savepoint 需要結合 rollback to sp1 一起使用,可以將儲存點 sp1 到 rollback to 之間的操作回滾掉。
只讀事務
- 表示在事務中執行的是一些只讀操作,如查詢,但是不會做insert、update、delete操作,資料庫內部對只讀事務可能會有一些效能上的優化
- 語法:
start transaction read only;
事務中的一些問題
- 這些問題主要是基於資料在多個事務中的可見性來說的。
髒讀
- 一個事務在執行的過程中讀取到了其他事務還沒有提交的資料。這個還是比較好理解的。
讀已提交
- 從字面上我們就可以理解,即一個事務操作過程中可以讀取到其他事務已經提交的資料。事務中的每次讀取操作,讀取到的都是資料庫中其他事務已提交的最新的資料(相當於當前讀)
可重複讀
- 一個事務操作中對於一個讀取操作不管多少次,讀取結果都是一樣的!
幻讀
- 幻讀在可重複讀的模式下才會出現,其他隔離級別中不會出現
事務的隔離級別
- 隔離級別分為4種:
- 讀未提交:READ-UNCOMMITTED
- 讀已提交:READ-COMMITTED
- 可重複讀:REPEATABLE-READ
- 序列:SERIALIZABLE
檢視
- 檢視好處。
- 簡化複製sql操作,不用知道實現細節
- 隔離了原始表,可以不讓使用檢視的人接觸原始的表,從而保護了原始資料,提高了安全性.
- 建立檢視
create view 檢視名
as
查詢語句;
- 修改檢視
- 方法一
create or replace view 檢視名 as 查詢語句;
- 方法二
alter view 檢視名 as 查詢語句;
- 刪除檢視
- 語句
drop view 檢視名去 [檢視名2] [檢視名n];
可以同時刪除多個檢視,多個檢視名稱之間用逗號隔開。
- 查詢檢視結構
# 方法一
desc 檢視名稱
# 方法二
show create view 檢視名稱;
- 更新檢視【基本不用】