#查询员工的姓名和原来的薪资和涨薪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:表