#查詢員工的姓名和原來的薪資和漲薪1000元后的薪資 SELECT ename,salary,salary + 1000 FROM t_employee; #查詢9/4的結果 SELECT 9/4 #查詢9/4的結果 SELECT 9 DIV 4 #查詢員工的姓名,和天天的薪資,假設每月的工做日是22天 SELECT ename AS "姓名", salary / 22 AS "日薪" FROM t_employee #查詢9%4的結果 SELECT 9%4, 9 MOD 4;
#查詢薪資大於20000的員工 SELECT * FROM t_employee WHERE salary > 20000; #查詢薪資等於9000 SELECT * FROM t_employee WHERE salary = 9000; #查詢部門編號不是1的員工 SELECT * FROM t_employee WHERE did != 1; SELECT * FROM t_employee WHERE did <> 1; #查詢獎金比例是NULL的員工 SELECT * FROM t_employee WHERE commission_pct <=> NULL; SELECT * FROM t_employee WHERE commission_pct IS NULL;
#查詢薪資高於10000 而且低於15000的女員工 SELECT * FROM t_employee WHERE salary > 10000 && salary <15000 AND gender = '女' #查詢薪資高於20000 或者 籍貫是 浙江 SELECT * FROM t_employee WHERE salary > 20000 || native_place = '浙江'; #查詢非浙江籍的男生 SELECT * FROM t_employee WHERE NOT native_place = '浙江' AND gender = '男'; #查詢獎金比例非空的員工 SELECT * FROM t_employee WHERE commission_pct IS NOT NULL;
#查詢籍貫是 「浙江」、「北京」、「上海」、「黑龍江」的員工 SELECT * FROM t_employee WHERE native_place IN ('浙江','上海','北京','黑龍江'); #查詢籍貫不是 「浙江」、「北京」、「上海」、「黑龍江」的員工 SELECT * FROM t_employee WHERE native_place NOT IN ('浙江','上海','北京','黑龍江');
#查詢薪資大於等於10000 而且小於等於15000的員工 SELECT * FROM t_employee WHERE salary BETWEEN 10000 AND 15000;
關聯查詢的結果一共有七種:
關聯查詢必須有兩張或兩張以上,如下用兩張來示例:mysql
(1)A ∩ B用內鏈接sql
(2)A用左鏈接數據庫
(3)A - (A ∩ B)用左鏈接
安全
(4)B 用右鏈接多線程
(5)B - A ∩ B用右鏈接
(6)A ∪ B本類應該用全外鏈接,如今用union併發
(7)A ∪ B - A ∩ B本類應該用全外鏈接,如今用union
函數
--形式一 select 字段列表 from A表 inner join B表 on 關聯條件 【where 其餘篩選條件】 --形式二 select 字段列表 from A表 , B表 where 關聯條件 【and 其餘篩選條件】
#查詢全部的員工的姓名和他所在部門的編號和部門的名稱,不包括那些沒有安排部門的員工 --形式一 select ename,t_employee.did,dname from t_employee inner join t_department on t_employee.did =t_department.did; --形式二 SELECT ename,t_employee.did,dname FROM t_employee , t_department WHERE t_employee.did = t_department.did ; #查詢全部的女員工的姓名和他所在部門的編號和部門的名稱,不包括那些沒有安排部門的員工 --1 SELECT ename,t_employee.did,dname FROM t_employee INNER JOIN t_department ON t_employee.did = t_department.did WHERE gender = '女'; --2 SELECT ename,t_employee.did,dname FROM t_employee , t_department WHERE t_employee.did = t_department.did AND gender = '女'; #查詢員工編號,員工的姓名,部門編號,部門名稱,職位編號,職位名稱 SELECT t_employee.eid, t_employee.`ename`, t_department.did,t_department.`dname`, t_job.`job_id`,t_job.`job_name` FROM t_employee INNER JOIN t_department INNER JOIN t_job ON t_employee.did = t_department.did AND t_employee.`job_id` = t_job.`job_id` SELECT t_employee.eid, t_employee.`ename`, t_department.did,t_department.`dname`, t_job.`job_id`,t_job.`job_name` FROM t_employee , t_department , t_job WHERE t_employee.did = t_department.did AND t_employee.`job_id` = t_job.`job_id`
左鏈接和右鏈接的區別:
(1)left換成right
(2)以左邊的表爲主仍是以右邊的表爲主spa
--左鏈接 select 字段列表 from A表 left join B表 on 關聯條件 where 從表的關聯字段 is null --右鏈接 select 字段列表 from A表 right join B表 on 關聯條件 where 從表的關聯字段 is null
#查詢全部員工和他的部門編號,部門名稱,包括那些沒有部門的員工 SELECT * FROM t_employee LEFT JOIN t_department ON t_employee.did = t_department.did #查詢全部沒有部門的員工 SELECT * FROM t_employee LEFT JOIN t_department ON t_employee.did = t_department.did WHERE t_employee.did IS NULL
mysql沒有全鏈接,使用union實現全鏈接的效果線程
select 字段列表 from A表 left join B表 on 關聯條件 union select 字段列表 from A表 right join B表 on 關聯條件
#查詢全部員工和部門信息,包括那些沒有部門的員工和沒有員工的部門 SELECT * FROM t_employee LEFT JOIN t_department ON t_employee.did = t_department.did UNION SELECT * FROM t_employee RIGHT JOIN t_department ON t_employee.did = t_department.did #查詢那些沒有部門的員工和沒有員工的部門 SELECT * FROM t_employee LEFT JOIN t_department ON t_employee.did = t_department.did WHERE t_employee.did IS NULL UNION SELECT * FROM t_employee RIGHT JOIN t_department ON t_employee.did = t_department.did WHERE t_employee.did IS NULL
以前:
select * from 表名稱 【where 條件】;
select 字段列表 from 表名稱 【where 條件】;3d
如今select
select語句的5個子句:
這5個子句能夠同時出現,也能夠只出現其中的一部分,其中若是有having前面必須有group by,可是有group by不必定有having
若是5個子句有多個同時出現的,那麼必須按照(1)-(5)的順序
#查詢全部的女員工 SELECT * FROM t_employee WHERE gender = '女'; #查詢全部女員工的姓名和薪資 SELECT ename,salary FROM t_employee WHERE gender = '女';
#查詢每一個部門的平均工資 SELECT did,AVG(salary) FROM t_employee GROUP BY did; #查詢每一個部門的平均工資,排除沒有部門的員工 SELECT did,AVG(salary) FROM t_employee WHERE did IS NOT NULL GROUP BY did ; #查詢每一個部門的女員工的最高工資 SELECT did,MAX(salary) FROM t_employee WHERE gender = '女' GROUP BY did; SELECT did,MAX(salary) FROM t_employee WHERE gender = '女' AND did IS NOT NULL GROUP BY did; #查詢男、女員工的平均工資 SELECT gender,AVG(salary) FROM t_employee GROUP BY gender; #查詢每一個部門的男、女員工的平均工資分別是多少 #先按部門再按男女 SELECT did, gender, AVG(salary) FROM t_employee GROUP BY did,gender; SELECT did, gender, AVG(salary) FROM t_employee WHERE did IS NOT NULL GROUP BY did,gender; #查詢每一個部門的工資總數 SELECT did,SUM(salary) FROM t_employee GROUP BY did; #查詢每一個部門的男、女員工的人數 SELECT did, gender, COUNT(*) FROM t_employee WHERE did IS NOT NULL GROUP BY did,gender;
having只用於group by分組統計語句
where和having的區別:
#查詢每一個部門的平均工資,只顯示平均工資在12000以上的 SELECT did,AVG(salary) FROM t_employee GROUP BY did HAVING AVG(salary) > 12000 #查詢每一個部門的最高工資,要求顯示最高工資低於12000 SELECT did,MAX(salary) FROM t_employee GROUP BY did HAVING MAX(salary) < 12000 SELECT did,MAX(salary) AS "m" FROM t_employee GROUP BY did HAVING m < 12000
按一個或多個字段對查詢結果進行排序,asc是升序,desc爲降序,默認是升序
#查詢員工的姓名和薪資,按照薪資的從高到低排序 SELECT ename,salary FROM t_employee ORDER BY salary DESC; #查詢員工的編號,姓名和薪資,按照薪資的從高到低排序,若是薪資相同,再按照編號升序排列 SELECT eid,ename,salary FROM t_employee ORDER BY salary DESC,eid ASC; #查詢每一個部門的平均工資,按照平均工資的升序排序 SELECT did,AVG(salary) FROM t_employee GROUP BY did ORDER BY AVG(salary) ASC; #查詢每一個部門的女員工的平均工資,按照平均工資的升序排序,而且只顯示平均工資高於12000的 SELECT did,AVG(salary) FROM t_employee WHERE gender = '女' GROUP BY did HAVING AVG(salary) > 12000 ORDER BY AVG(salary) ASC;
limit m,n
m = (page - 1)*每頁的記錄數
n = 每頁的記錄數
#查詢員工信息,每頁顯示10條,顯示第一頁 SELECT * FROM t_employee LIMIT 0,10 #查詢員工信息,每頁顯示10條,顯示第二頁 SELECT * FROM t_employee LIMIT 10,10 #查詢每一個部門的女員工的平均工資,按照平均工資的升序排序,而且只顯示平均工資高於12000的, #每頁顯示1條,顯示第二頁 SELECT did,AVG(salary) FROM t_employee WHERE gender = '女' GROUP BY did HAVING AVG(salary) > 12000 ORDER BY AVG(salary) ASC LIMIT 1,1;
某些狀況下,當進行一個查詢時,須要的條件或數據要用另一個 select 語句的結果,這個時候,就要用到子查詢。
條件的運算符分爲兩類:
=,>,>=,<,<=,!= 後面接子查詢的結果必須是「單值」
in, = any, >all,>= ,<all..... 後面接子查詢的結果能夠是「多值」
#查詢全公司最高工資的員工的信息 #(1)查詢最高工資 SELECT MAX(salary) FROM t_employee; #(2)查詢最高工資的員工的信息 SELECT * FROM t_employee WHERE salary = 130990 #(3)合起來 SELECT * FROM t_employee WHERE salary = (SELECT MAX(salary) FROM t_employee) -------------------------------------------------------------------------- #查詢和孫紅雷,劉燁,范冰冰三我的中任意一個工資同樣的員工 SELECT * FROM t_employee WHERE salary IN (SELECT salary FROM t_employee WHERE ename IN ('孫紅雷','劉燁','范冰冰')) SELECT * FROM t_employee WHERE salary = ANY (SELECT salary FROM t_employee WHERE ename IN ('孫紅雷','劉燁','范冰冰')) ------------------------------------------------------------------------- #查詢比李冰冰工資高的女員工 SELECT * FROM t_employee WHERE gender = '女' AND salary > (SELECT salary FROM t_employee WHERE ename = '李冰冰'); #查詢全公司最高工資的員工的信息 SELECT * FROM t_employee WHERE salary >= ALL(SELECT salary FROM t_employee)
查詢每一個部門編號,部門名稱,和平均工資,排除沒有部門的員工,包括那些沒有員工的部門
SELECT t_department.*, temp.pingjun FROM t_department LEFT JOIN (SELECT did,AVG(salary) AS pingjun FROM t_employee WHERE did IS NOT NULL GROUP BY did) AS temp ON t_department.did = temp.did
#查詢部門信息,該部門必須有員工 SELECT * FROM t_department WHERE EXISTS (SELECT * FROM t_employee WHERE t_employee.did = t_department.did)
#把SELECT * FROM t_department的每一行記錄,根據t_employee.did = t_department.did,代入到(SELECT * FROM t_employee)中查,若是能夠查到結果,說明該行要留下,不然就排除掉
#使用內鏈接查詢,也能夠實現 SELECT DISTINCT t_department.* FROM t_department INNER JOIN t_employee ON t_employee.did = t_department.did
ABS(x) |
返回x的絕對值 |
CEIL(x) |
返回大於x的最小整數值 |
FLOOR(x) |
返回大於x的最大整數值 |
MOD(x,y) |
返回x/y的模 |
RAND(x) |
返回0~1的隨機值 |
ROUND(x,y) |
返回參數x的四捨五入的有y位的小數的值 |
TRUNCATE(x,y) |
返回數字x截斷爲y位小數的結果 |
SQRT(x) |
返回x的平方根 |
POW(x,y) |
返回x的y次方 |
CONCAT(S1,S2,......,Sn) |
鏈接S1,S2,......,Sn爲一個字符串 |
CONCAT_WS(s, S1,S2,......,Sn) |
同CONCAT(s1,s2,...)函數,可是每一個字符串之間要加上s |
CHAR_LENGTH(s) |
返回字符串s的字符數 |
LENGTH(s) |
返回字符串s的字節數,和字符集有關 |
INSERT(str, index , len, instr) |
將字符串str從第index位置開始,len個字符長的子串替換爲字符串instr |
UPPER(s) 或 UCASE(s) |
將字符串s的全部字母轉成大寫字母 |
LOWER(s) 或LCASE(s) |
將字符串s的全部字母轉成小寫字母 |
LEFT(s,n) |
返回字符串s最左邊的n個字符 |
RIGHT(s,n) |
返回字符串s最右邊的n個字符 |
LPAD(str, len, pad) |
用字符串pad對str最左邊進行填充,直到str的長度爲len個字符 |
RPAD(str ,len, pad) |
用字符串pad對str最右邊進行填充,直到str的長度爲len個字符 |
LTRIM(s) |
去掉字符串s左側的空格 |
RTRIM(s) |
去掉字符串s右側的空格 |
TRIM(s) |
去掉字符串s開始與結尾的空格 |
TRIM(【BOTH 】s1 FROM s) |
去掉字符串s開始與結尾的s1 |
TRIM(【LEADING】s1 FROM s) |
去掉字符串s開始處的s1 |
TRIM(【TRAILING】s1 FROM s) |
去掉字符串s結尾處的s1 |
REPEAT(str, n) |
返回str重複n次的結果 |
REPLACE(str, a, b) |
用字符串b替換字符串str中全部出現的字符串a |
STRCMP(s1,s2) |
比較字符串s1,s2 |
SUBSTRING(s,index,len) |
返回從字符串s的index位置其len個字符 |
CURDATE() 或 CURRENT_DATE() |
返回當前日期 |
CURTIME() 或 CURRENT_TIME() |
返回當前時間 |
NOW()
SYSDATE() CURRENT_TIMESTAMP() LOCALTIME() LOCALTIMESTAMP() |
返回當前系統日期時間 |
YEAR(date) MONTH(date) DAY(date) HOUR(time) MINUTE(time) SECOND(time) |
返回具體的時間值 |
WEEK(date) WEEKOFYEAR(date) |
返回一年中的第幾周 |
DAYOFWEEK() |
返回周幾,注意:週日是1,週一是2,。。。週六是7 |
WEEKDAY(date) |
返回周幾,注意,周1是0,周2是1,。。。週日是6 |
DAYNAME(date) |
返回星期:MONDAY,TUESDAY.....SUNDAY |
MONTHNAME(date) |
返回月份:January,。。。。。 |
DATEDIFF(date1,date2) TIMEDIFF(time1, time2) |
返回date1 - date2的日期間隔 返回time1 - time2的時間間隔 |
DATE_ADD(datetime, INTERVAL expr type) |
返回與給定日期時間相差INTERVAL時間段的日期時間 |
DATE_FORMAT(datetime ,fmt) |
按照字符串fmt格式化日期datetime值 |
STR_TO_DATE(str, fmt) |
按照字符串fmt對str進行解析,解析爲一個日期 |
IF(value,t ,f) |
若是value是真,返回t,不然返回f |
IFNULL(value1, value2) |
若是value1不爲空,返回value1,不然返回value2 |
CASE WHEN 條件1 THEN result1 WHEN 條件2 THEN result2 .... [ELSE resultn] END |
至關於Java的if...else if... |
CASE expr WHEN 常量值1 THEN 值1 WHEN 常量值1 THEN 值1 .... [ELSE 值n] END |
至關於Java的switch |
|
SELECT ename ,CASE WHEN salary>=15000 THEN '高薪' WHEN salary>=10000 THEN '潛力股' WHEN salary>=8000 THEN '屌絲' ELSE '草根' END FROM t_employee; |
|
SELECT oid,`status`, CASE `status` WHEN 1 THEN '未付款' WHEN 2 THEN '已付款' WHEN 3 THEN '已發貨' WHEN 4 THEN '確認收貨' ELSE '無效訂單' END FROM t_order; |
表示一組操做(sql),要麼同時成功,要麼同時失敗,那麼這種操做就構成了一個事務。
例如:
張三 給 李四 轉帳 500元
(1)把張三的餘額減小500
...
(2)把李四的餘額增長500
不容許出現:張三的錢減小了500,而李四的錢沒有加。
須要在(1)以前開啓事務,若是同時成功,那麼就提交這個事務,不然就回滾(還原到(1))以前的狀態。
mysql默認狀況下是自動提交事務模式,即執行一句,自動提交一句,一旦提交就不能回滾。
若是想要開始手動提交模式,那麼能夠經過如下語句完成: set autocommit = false;
建表的時候,選擇 Innodb引擎才支持事務
#開啓手動提交模式,做用範圍是一次鏈接(從登陸到退出) SET autocommit = FALSE; DELETE FROM t_department WHERE did > 5; INSERT INTO t_department VALUES(NULL,'yy','yyyy'); ROLLBACK; #COMMIT;
mysql中只有Innodb引擎才支持事務。
事務只對DML語句有效,對DDL語句無效。
對於同時運行的多個事務(多線程併發), 當這些事務訪問數據庫中相同的數據時, 若是沒有采起必要的隔離機制, 就會致使各類併發問題: (問題的本質就是線程安全問題,共享數據的問題)
一個事務讀取了另外一個事務還未提交的數據
一個事務讀取了另外一個事務「修改」已提交的數據,致使一個事務期間對同一個數據的先後兩次讀取,結果不一致。
一個事務讀取了另外一個事務新增長並已經提交的數據,致使一個事務期間記錄數不同。
一個事務讀取了另外一個事務刪除並已經提交的數據,致使一個事務期間記錄數不同。
事務的隔離級別:
(1)READ-UNCOMMITTED:讀取未提交的數據
(2)READ-COMMITTED:讀取已提交的數據
(3)REPEATABLE-READ:可重複讀取
(4)SERIALIZABLE:序列化
mysql的默認隔離級別是:(3)
若是當前鏈接的隔離級別是READ-UNCOMMITTED,你會讀取到別人未提交的數據,這個現象稱爲髒讀。 若是避免「髒讀」,就是提升隔離級別,提升爲READ-COMMITTED或它以上。 若是當前鏈接的隔離級別是READ-UNCOMMITTED和READ-COMMITTED,都會出現不可重複的的現象, 若是要避免「不可重複讀」,仍是提升隔離級別,提升爲REPEATABLE-READ或它以上。 (3)REPEATABLE-READ和(4)SERIALIZABLE都能避免髒讀、不可重複讀、幻讀,那麼有什麼區別呢? REPEATABLE-READ:行 SERIALIZABLE:表