一:表單查詢
消除重複
select distinct 列名,列名 from 表名;
當兩個列裏面的所有值都相同的時候,就消除重複
算術操作符
如果算總和,有的列有null,則:
SELECT IFNULL(expr1,expr2) from 表名;
如果expr1不是null, IFNULL()返回expr1, 否則它返回expr2
空值判斷
空值的任何算術表達式都等於空.
select * from 表名 where 列名 is null;
select * from 表名 where 列名 is not null;
限定查詢
1:字符串和日期要用單引號擴起來
2:數字類型直接書寫
3:字符串是大小寫不銘感的,日期值是格式銘感的
4:字符串銘感,需要添加binary關鍵字
比較運算符
1: = != <> > >= < <= 等於和不等於
2:BETWEEN...AND...;在倆值之間(包含開始和結尾);
3:IN(list);匹配列出的值;
4:LIKE:匹配字符串模式;
5:IS NULL:是否爲空;
邏輯運算符
AND:如果組合的條件是true,返回true.
OR:如果組合的條件之一是true,返回true.
NOT:如果下面的條件是false,返回true.
優先級:比較運算符 > NOT > AND > OR
結果排序
使用ORDER BY 子句將記錄排序
ASC:升序,缺省 DESC:降序
ORDER BY 子句出現在SELECT語句的最後 可以使用別名
二:MySQL查詢函數
多行函數:多條數據同時計算,最終得到一條結果數據,也稱爲聚集函數,分組函數,主要用於完成一些統計功能.
AVG平均,SUM總和,COUNT總和,MAX最大,MIN最小
單行函數:將每條數據進行獨立的計算,然後每條數據得到一條結果.
1:字符函數
LOWER(str):返回字符串str變爲小寫字母的字符
UPPER(str):返回字符串str變爲大寫字母的字符
CONCAT(str1,str2...);
1:返回結果爲連接參數產生的字符串
2:如有任何一個參數爲null,則返回值爲null
3:允許有一個或多個參數
CHAR_LENGTH:字符串長度;
LENGTH:字符串長度(單位爲字節);
LPAD(str,len,padstr)
1:返回字符串str,其左邊由字符串padstr,填充到len字符長度.
2:假如str的長度大於len,則返回值被縮短至len字符.
LTRIM(str):左邊空格被trim掉;
RTRIM(str):右邊空格被trim掉;
REPLACE(str,from_str,to_str);
1:在str中把from_str,全部替換爲to_str;
2:大小寫銘感;
SUBSTRING(str,pos);
從字符串str返回一個子字符串,起始於位置pos
SUBSTRING(str,pos,len);
從字符串str返回一個長度同len字符相同的子字符串,起始於位置pos.
2:數字函數
ABS(x):返回一個數字的絕對值;
MOD(N,M):返回N被M除去的餘數;
CEL(X):返回不小於X的最小整數值;
FLOOR(x):返回不大於X的最大整數值;
ROUND(X)/ROUND(X,D):
1:返回參數X,其值接近於最近似的整數.
2:在有2個參數的情況下,返回X,其值保留到小數點後D位,而第D位的保留方式爲四捨五入.
3:日期函數
SATE_ADD(date,INTERVAL exper type) / DATE_SUB(date,INTERVAL expr type)向日期添加指定的時間間隔
1:執行日期運算;
2:date 是一個DATETIME 或 DATE值,用來指定起始時間;
3:exper 是一個字符串表達式,用來指定從起始日期添加或減去的時間間隔;
4:type 爲關鍵字,它指示了表達式被解釋的方式
type 參數可以是以下值:MICROSECOND SECOND MINUTE HOUR
current_date() 當前日期
current_time() 當前時間
DATEDIFF(expr,expr2): 返回起始時間expr和結束時間expr2之間的天數
獲取日期時間中某個段
DAY HOUR MINUTE MONTH YEAR
LAST_DAY : 獲取一個日期或日期時間值,返回該月最後一天對應的值
UNIX_TIMESTAMP(date): 它會將參數值以'1970-01-01 00:00:00'GMT後的秒數的形式返回
FROM_UNIXTIME(unix_timestamp).FROM_UNIXTIME(unix_timestamp,format):返回'YYYY-MM-DD HH:MM:SS'或指定format的日期
4:轉換函數
數字和字符串:
FORMAT(X,D)
將數字X的格式寫爲'#,###,###,##',以四捨五入的方式保留小數點後D位,並將結果以字符串的形式返回
若D爲0,則返回結果不帶有小數點,或不含小數部分.
日期和字符串的轉換:
格式:DATE_FORMAT(date,format):把日期轉換爲字符串.
SELECT DATE_FORMAT(NOW(),'%Y/%m/%d') FROM DUAL;
STR_TO_DATE(str,format):把字符串轉換爲日期.
select str_to_date('2018/03/17','%Y/%m/%d') from dual;
5:單行函數的嵌套
單行函數可被嵌入到任何層,在嵌套的時候,最內層的函數最先被執行,執行的結果被傳遞到它的上層函數,
作爲參數使用,然後依次從內向外執行,直到所有的函數執行完.
二:分組查詢
使用GROUP BY語法:
1:出現在SELECT列表中的字段,如果出現的位置不是在組函數中,那麼必須出現在GROUP BY子句中
2:在GROUP BY子句中出現的字段,可以不出現在SELECT列表中
3:如果沒有GROUP BY子句SELECT列表中的任何列或表達式不能使用統計函數:
執行順序:1.FROM 2.WHERE 3.GROUP BY 4.HAVING 5.SELECT 6.DISTINCT 7.UNION 8.ORDER BY
三:多表查詢
笛卡爾乘積:
多表查詢時沒有連接條件的表關係返回的結果.
多表查詢會產生笛卡爾積:
假設集合A={a,b}, 集合B={0,1,2} 則兩個集合的笛卡爾積爲{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}.
實際運行環境下,應避免使用全笛卡爾積.
select * form emp,dept;
解決方案:在where加入有效的連接條件-->等值連接
注意: 連接N張表,至少需要N-1個連接條件.
外鍵約束(POREIGN KEY: FK):用來限定B表中的某一列的數據來源於A表中的主鍵列,不允許亂寫.
1:在employee表中dept_id列的值,就應該來源於department表中的id列,不允許亂寫.
2:和查詢沒有關係,沒有外鍵不影響查詢,僅僅是在INSERT數據時會做數據檢查.
3:在開發中要支持外鍵和事務,必須使用InnoDB存儲引擎,不能使用MyISAM.
4:使用外鍵性能較低,在開發中往往刪除掉外鍵約束,所有的數據合法性檢查交給Java代碼.
5:外鍵在many方,多個員工同屬於一個部門.
6:在添加many方時,往往是通過下拉列表去選擇noe方,而不是直接寫.
隱式連接:
多表查詢:
1):內連接查詢(隱士/顯示)
2):左外連接查詢,左連接查詢
3):右外連接查詢,右連接查詢
4):全外連接查詢
5):自連接查詢.
一定要記住右圖.
A和B好比是兩張表.
紅色表示查詢的結果.
紅色的位置對應的是什麼連接查詢.
![所有的連接表示圖](//img-blog.csdn.net/20180318112612688?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
顯示連接:
內連接:
隱式內連接的查詢語法:
SELECT <select_list> FROM 表名稱A,表名稱B WHERE 查詢條件 AND 消除笛卡爾積的連接條件 [ORDER BY 排序字段[ASC|DESC]..]];
在WHERE 子句中寫入連接條件:
當多個表中有重名列時,必須在列的名字前加上表名作爲前綴,一般的是給表起別名.
select e.ename,e.sal,d.dname,sg.grade from emp e ,dept d ,salgrade sg where
e.deptno = d.deptno AND e.sal between sg.losal and sg.hisal;
顯示內連接的查詢語法:
SELECT <select_list> FROM A [INNER] JOIN B ON 消除笛卡爾積的連接條件 [join..]
自然連接的條件是基於表中所有同名列的等值連接
爲了設置任意的連接條件或者指定連接的列,需要使用ON子句
連接條件與其他查詢條件分開書寫,使用ON子句使查詢語句更容易理解.
select e.ename,e.sal,d.dname from emp e join dept d on e.deptno = d.deptno;
select e.ename,e.sal,d.dname from emp e join dept d using (deptno);
執行順序:先執行join再執行where
外連接:
外連接查詢,內連接最大的問題在於必須匹配條件才能被查詢出來,而在開發中條件存在不
匹配的情況,比如新插入一條員工信息,卻還沒有分配部門,此時就查詢不出該員工.
------------------------------------------------------------------------
SELECT <select_list> from A left join B on A和B的連接條件
左外連接查詢(left join). 左連接查詢: 查詢出join左邊表中所以數據,右邊表如果不匹配使用null填充.
SELECT <select_list> from B right join A on A和B的連接條件
右外連接查詢(right join). 右連接查詢: 查詢出join右邊表中所以數據,左邊表如果不匹配使用null填充.
查詢出每個部門員工的人數.
select d.dname,count(e.ename) from dept d left join emp e on e.deptno = d.deptno group by d.dname;
+------------+----------------+
| dname | count(e.ename) |
+------------+----------------+
| ACCOUNTING | 0 |
| OPERATIONS | 0 |
| RESEARCH | 2 |
| SALES | 3 |
+------------+----------------+
查詢出至少有一個員工的所有部門編號,名稱,並統計出這些部門的平均工資,最低工資,最高工資
select d.deptno,d.dname ,avg(e.sal),min(e.sal),max(e.sal) from dept d join emp e on
d.deptno = e.deptno group by d.deptno,d.dname;
+--------+----------+------------+------------+------------+
| deptno | dname | avg(e.sal) | min(e.sal) | max(e.sal) |
+--------+----------+------------+------------+------------+
| 20 | RESEARCH | 1887.5000 | 800 | 2975 |
| 30 | SALES | 1366.6667 | 1250 | 1600 |
+--------+----------+------------+------------+------------+
全連接:
全外連接查詢:
FULL OUTER JOIN 中會返回所有右邊表中的行和所有的左邊表中的行,即使在左邊的表中沒有可對應的列值或者右邊的表中沒有可對應的列
MYSQL中暫時不支持全連接 可以通過union左右連接來完成;
自連接查詢:
自連接查詢:把一張表看成是兩張表,使用別名區分.
四:子查詢
子查詢的分類:是根據子查詢的結果集來劃分的.
情況1:單行單列子查詢:只包含一個字段的查詢,返回的查詢結果也只包含一行數據:放到WHERE後面.
情況2:多行單列子查詢:只包含了一個字段,但返回的查詢結果可能多行或者零行:放到WHERE後面
情況3:多列子查詢:包含多個字段的返回,查詢結構可能是單行或者多行,好比是一張臨時表,放到FROM後面.
情況1:單行單列子查詢:
字查詢返回一行一列記錄,好比是一個值
1:返回一行記錄
2:使用單行記錄比較運算符:=;>;>=;<;<=;<> (針對於一個值的運算符)
情況2:多行子查詢返回多行單列:好比是多個值
1:返回多行
2:使用多行比較運算符
IN :與列表中的任意一個值相等
ANY:與子查詢返回的任意一個值比較
1):=ANY:此時和IN操作符相等
2):>ANY:大於子查詢中最小的數據
3):<ANY:小於子查詢中最大的數據
ALL:與子查詢返回的每一個值比較
1):>ALL:大於子查詢中最大的數據.
2):<ALL:小於子查詢中最小的數據.
情況3:多列子查詢
子查詢返回的結果是多行多列/一行多列,只要是多列,就可以看成一張表.
一般會把多列子查詢返回的結果當成一個臨時表,接着在臨時表上繼續查詢或者連接查詢;
注意,多行多列的子查詢返回的結果必須要設置一個臨時表的名稱;
UNION操作符用於合併兩個或多個SELECT語句的結果集.
注意:
1:UNION內部的SELECT語句必須擁有相同的數量列.
2:列也必須擁有兼容的數據類型.
3:每條SELECT語句中的列的順序必須相同.
4:UNION結果集中的列名總是等於UNION中第一個SELECT語句中的列名
5:UNION操作符選取不同的值,如果允許重複的值,請使用UNION ALL(性能高).
五:DML和TCL
數據庫事務概念:
![事務的基本原理](//img-blog.csdn.net/20180318213147654?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
![事務的隔離](//img-blog.csdn.net/20180318213219155?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
這裏最嚴重的就是丟失更新問題,解決方案:
方案1:悲觀鎖.事務A在操作時,悲觀認爲其他事務會進來干擾自己.
方案2:樂觀鎖.事務A在操作時,樂觀認爲其他事務不會進來干擾自己.
悲觀鎖:
使用數據庫自身的排他鎖機制(寫鎖)(排斥其他鎖).
DML操作會自動加上排它鎖.(增刪改操作)
DQL操作需要我們手動加上排他鎖.(查詢操作)
SELECT * FROM 表名 FOR UPDATE.
樂觀鎖
![樂觀鎖的操作步驟](//img-blog.csdn.net/20180318221215344?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
SQL加強課程,重點掌握
1:權限管理,至少會使用客戶端配置,分配用戶和權限即可.
2:單表和多表查詢(內連接/外連接/自連接)
3:查詢行數
4:分組查詢
5:子查詢
6:悲觀鎖和樂觀鎖的原理
MYSQL高級:
執行流程 SQL優化 explain profile 索引原理和設計 主從複製/讀寫分離