一、MySQL 常用命令
1.查看当前所有的数据库
show databases;
2.打开指定的库
use 库名;
3.查看当前库的所有表
show tables;
4.查看指定库的所有数据表
show tables from 库名;
5.创建表
create table 表名(
列名 列类型,
列名 列类型
...
);
6.查看表结构
desc 表名;
7.查看服务器版本
(1)方式一:登录到mysql服务端
select version();
(2)没有登录到mysql服务端
mysql --version
或
mysql -V
二、MySQL语法规范
1.不区分大小写,但是建议关键字大写,表名、列表小写
2.每条命令用分号结尾
3.每天命令根据需要可以缩进或换行
三、基础查询
1.查询表中单个字段
SELECT last_name FROM employees;
2.查询表中多个字段
SELECT last_name,salary,email FROM employees;
3.查询表中所有字段
SELECT * FROM employees;
4.查询常量值
SELECT 100;
SELECT 'john';
5.查询表达式
SELECT 100%98;
6.取别名
(1)方式一:使用AS
SELECT last_name AS xing, first_name AS ming FROM employees;
(2)方式二:使用空格
SELECT last_name xing, first_name ming FROM employees;
7.去重
SELECT DISTINCT department_id FROM employees;
8.加号+
(1)两个操作数都为数值型,则做加法运算
SELECT 100+90;
(2)一方为数值型,一方为字符型,则试图将字符型转为数值型,如果转成功,则做加法运算,否则将字符型转为0
SELECT '123'+90;
SELECT 'john'+90;
(3)有一方为null, 结果肯定为null
SELECT null+90;
9. 拼接
#SELECT CONCAT(a, b, c) AS 结果
SELECT CONCAT(last_name, ',', first_name, ',' IF_NULL(comission_pct, 0)) as result FROM employees;
四、条件查询
语法:
select 查询列表 from 表名 where 筛选条件;
1.条件运算符:>、<、= 、!= 、<>、>=、<=
(1)查询工资大于12000的员工信息
SELECT * FROM employees WHERE salary > 12000;
(2)查询部门编号不等于90号的员工名和部门编号
SELECT last_name, department_id FROM employees WHERE department_id != 90;
或
SELECT last_name, department_id FROM employees WHERE department_id <> 90;
2.逻辑运算符:&&、 ||、 !、and、or 、not
(1)查询工资在1000到2000之间的员工名、工资以及奖金
SELECT last_name, salary, commision_pct FROM employees WHERE salary >= 10000 and salary <= 20000;
(2)查询部门编号不是在90到110 之间,或者工资高于15000的员工信息
SELECT * FROM employees WHERE department_id < 90 OR department_id > 110 OR salary >15000;
或
SELECT * FROM employees WHERE NOT (department_id >= 90 AND department_id <= 110) OR salary > 15000;
3.模糊查询:like、between and、in、is null、is not null
(1)查询员工名中包含字符a的员工信息(百分号)
SELECT * FROM employees WHERE last_name LIKE '%a%';
(2)查询员工名中第三个字符为e,第五个字符为a的员工名和工资(下划线)
SELECT last_name, salary FROM employees WHERE last_name LIKE '__e_a%';
(3)查询员工名中第二个字符为下划线的员工名(斜杠转义)
SELECT last_name FROM employees WHERE last_name LIKE '_\_%';
或
SELECT last_name FROM employees WHERE LIKE '_$_%' ESCAPE '$';
(4)查询员工编号在100-120之间的员工信息
SELECT * FROM employees WHERE employee_id BETWEEN 100 and 200;
#等价于下面的
SELECT * FROM employees WHERE employee_id >= 100 AND employee_id <= 200;
(5)查询工资不在8000-17000的员工的姓名和工资, 按工资降序
SELECT last_name, salary FROM employees WHERE salary NOT BETWEEN 8000 AND 17000;
(6)查询员工的工种编号是IT_PROG、AD_VP、AD_PRES中的一个员工名和工种编号
SELECT last_name, job_id FROM employees WHERE job_id IN (IT_PROG, AD_VP, AD_PRES);
#等同于下面
SELECT last_name, job_id FROM employees WHERE job_id = 'IT_PROG' OR job_id = 'AD_VP' OR job_id = 'AD_PRES';
(7) 查询没有奖金的员工名和奖金率
SELECT last_name, commision_pct FROM employees WHERE commission_pct IS NULL;
五、排序查询
语法:select 查询列表 from 表名 【where筛选条件】order by 排序列表 【asc|desc】
1.查询员工工资信息,要求从高到低排序
SELECT * FROM employees ORDER BY salary DESC;
2.查询部门编号>=90的员工信息,按入职时间的先后顺序【添加筛选条件】
SELECT * FROM employees WHERE department_id >= 90 ORDER BY hiredate ASC;
3.按年薪的高低显示员工的信息和年薪【按表达式排序】
SELECT *, salary*12(1+IFNULL(commission_pct, 0)) AS year_salary ORDER BY year_salary DESC;
4.按姓名的长度显示员工的姓名和工资【按函数排序】
SELECT LENGTH(last_name) AS name_length, last_name, salary FROM employees ORDER BY name_length DESC;
六、常见函数
1.字符函数
(1)length 获取参数值的字节个数
SELECT LENGTH('john'); #4
SELECT LENGTH('张三丰hahaha'); #15,一个中文占3个字节
(2)concat 拼接字符串
SELECT concat(last_name, '_', first_name) AS name FROM employees;
(3)upper、lower
SELECT UPPER('john');
SELECT LOWER('JOHN');
SELECT CONCAT(UPPER(last_name), LOWER(first_name)) AS name FROM employees;
(4)substr、substring,索引从1开始
SELECT SUBSTR('李莫愁爱上了陆展元', 7) AS out_put; # 陆展元
SELECT SUBSTR('李莫愁爱上了陆展元', 0, 3) AS out_put; #李莫愁
#姓名中首字符大写,其它字符小写,然后用下划线_拼接
SELECT CONCAT(UPPER(SUBSTR(last_name, 1, 2)), '_', LOWER(SUBSTR(SUBSTR(last_name, 2))) AS out_put FROM employees;
(5)instr 返回子串第一次出现的索引,如果找不到返回0
SELECT INSTR('杨不悔爱上了殷六侠', '殷六侠') AS out_put; #7
(6)trim
SELECT LENGTH(TRIM(' 张翠山 ')) AS out_put;
SELECT TRIM('a' FROM 'aaaaaa张翠山aaaaa') AS out_put; #张翠山
(7)lpad 用指定的字符实现左填充指定长度, lpad 用指定的字符实现右填充指定长度
SELECT LPAD('殷素素', 16, '*') AS out_put; #*************殷素素
SELECT LPAD('殷素素', 12, 'ab') AS out_put;#殷素素ababababa
(8)replace 替换
SELECT REPLACE('周芷若爱上了张无忌周芷若', '周芷若', '赵敏') AS out_put; #赵敏爱上了张无忌赵敏
2.数学函数
(1)round四舍五入
SELECT ROUND(-1.55); #-2
SELECT ROUND(1.567, 2); #1.57
(2)ceil 向上取整,返回>=该参数的最小整数
SELECT CEIL(1.2); #2
(3)floor 向上取整,返回<=该参数的最小整数
SELECT FLOOR(9.99); #9
SELECT FLOOR(-10); #-10
(4)truncate 截断
SELECT TRUNCATE(1.79999, 1); #1.7
(5)mod 取余
SELECT MOD(10, 3); #1
3.日期函数
(1)now 返回系统当前日期+时间
SELECT NOW(); #2021-05-22 15:01:54
(2)curdate 返回系统当前日期, 不包含时间
SELECT CURDATE();#2021-05-22
(3)curtime 返回系统当前时间,不包含日期
SELECT CURTIME();#15:04:46
(4)获取指定的部分,年月日时分秒
SELECT YEAR(NOW()) AS year; #2021
SELECT YEAR(hiredate) AS year FROM employees;
SELECT YEAR('2021-05-22') AS year;
SELECT STR_TO_DATE('2021-5-22', '%Y-%c-%d') AS out_put; #2021-05-22
(5)date_format 将日期转化为字符
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日') AS ymd; #2021年05月22日
4.其它函数
(1)当前数据库版本号
SELECT VERSION();
(2)当前数据库
SELECT DATABASE();
(3)当前用户
SELECT USER();
(4)返回字符的密码形式
SELECT PASSWORD('mysql');
(5)返回字符的md5加密结果
SELECT MD5('mysql');
5.流程控制函数
(1)if 函数,能实现if else 效果
SELECT IF(10 > 5, '大', '小'); #大
SELECT last_name, commission_pct IF(commission IS NULL, '没奖金', '有奖金') AS bonus FROM employees;
(2)case函数,类似switch case的效果
语法:case 要判断的字段或表达式
when 常量1 then 要显示的值1 或语句1
when 常量2 then 要显示的值2 或语句2
...
else 要显示的值或语句
end
SELECT salary AS original_salary, department_id,
CASE department_id
WHEN 30 THEN salary*1.1
WHEN 40 THEN salary*1.2
WHEN 50 THEN salary*1.3
ELSE salary
END AS new_salary
FROM employees;
SELECT salary,
CASE salary
WHEN salary > 20000 THEN 'A'
WHEN salary > 15000 THEN 'B'
WHEN salary > 10000 THEN 'C'
ELSE 'D'
END AS salary_level FROM employees;
6.分组函数(聚合函数或统计函数)
(1)sum求和
SELECT SUM(salary) FROM employees;
(2)avg平均值
SELECT AVG(salary) FROM employees;
(3)max最大值
SELECT MAX(salary) FROM employees;
(4)min最小值
SELECT MIN(salary) FROM employees;
(5)count个数
SELECT COUNT(salary) FROM employees;
SELECT SUM(salary) AS sum, MAX(salary) AS max, MIN(salary) AS min, ROUND(AVG(salary), 2) AS avg, COUNT(salary) AS count FROM employees;
SELECT COUNT(*) FROM employees;
七、分组查询
语法:select 分组函数,列 from 表 【where筛选条件】 group by 分组的列表 【order by 子句】
注意:①查询列表必须是分组函数和group by 后出现的字段
②分组函数做条件肯定放在having子句中
③能用分组前筛选的,优先考虑使用分组前筛选
特点:分组查询的筛选条件分为2类:
数据源 | 位置 | 关键字 | |
分组前筛选 | 原始表 | group by 子句的前面 | where |
分组后筛选 | 分组后的结果集 | group by 子句的后面 | having |
1.查询每个工种的最高工资
SELECT MAX(salary), job_id FROM employees GROUP BY job_id;
2.查询每个位置上的部门个数
SELECT COUNT(*), location_id FROM departments GROUP BY location_id;
3.查询邮箱中包含a字符的,每个部门的平均工资
SELECT AVG(salary), department_id FROM employees WHERE email LIKE '%a%' GROUP BY department_id;
4.查询有奖金的每个领导手下员工的最高工资
SELECT MAX(salary), manager_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY manager_id;
5.查询哪个部门的员工数大于2
(1)查询每个部门的员工数
SELECT COUNT(*), department_id FROM employees GROUP BY department_id;
(2)根据(1)的结果进行筛选,查询哪个部门的员工数大于2(添加分组后的筛选条件,having)
SELECT COUNT(*), department_id FROM employees GROUP BY department_id HAVING count(*) > 2;
6.查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
(1)查询每个工种有奖金的员工的最高工资
SELECT MAX(salary),job_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY job_id;
(2)根据(1)结果进行筛选,最高工资>12000
SELECT MAX(salary), job_id FROM employees WHERE commission_pct is NOT NULL GROUP BY job_id HAVING MAX(salary) > 12000;
7.查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资
(1)查询领导编号>102的每个领导手下的最低工资
SELECT MIN(salary),manager_id FROM employees WHERE manager_id > 102 GROUP BY manager_id;
(2)最低工资大于5000
SELECT MIN(salary),manager_id FROM employees WHERE manager_id > 102 GROUP BY manager_id HAVING MIN(salary) > 5000;
8.按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数大于5的有哪些
SELECT COUNT(*) C, LENGTH(last_name) len_name FROM employees GROUP BY len_name HAVING c > 5;
9.查询每个部门每个工种的员工的平均工资(多多个字段分组)
SELECT AVG(salary), department_id, job_id FROM employees GROUP BY department_id, job_id;
10.查询每个部门每个工种的员工的平均工资,按照平均工资从高到低排序
SELECT AVG(salary) asa, department_id, job_id FROM employees GROUP BY department_id, job_id ORDER BY asa DESC;
八、连接查询(SQL1992)
又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔积现象:表1有m行,表2有n行,结果m*n行
如何避免:添加有效的连接
按功能分类:
内连接:等值连接、非等值连接、自连接
外连接:左外连接、右外连接、全连接
交叉连接
等值连接示例
注意事项:结果为多表的交集部分;n表连接至少需要n-1个连接条件;多表的顺序没有要求;一般需要为表起别名;可以搭配子句使用,如排序、分组、筛选
1.查询员工名对应的部门名(等值连接)
SELECT last_name, department_name FROM employees, departments WHERE employees.`department_id` = departments.`department_id`;
2.查询员工名、工种号、工种名
SELECT last_name, .job_id, job_title
FROM employees e, jobs j
WHERE e.`job_id` = j.`job_id`;
3.查询有奖金的员工名、部门名
SELECT last_name, department_name
FROM employees e, departments d
WHERE e.`department_id` = d.`department_id`
AND e.commission_pct IS NOT NULL;
3.查询城市名中第二个字符为o的部门名和城市名
SELECT department_name, city
FROM departmens d, locations l
WHERE d.`location_id` = l.`location_id`
AND city LIKE '%a%';
4. 查询每个城市的部门个数(添加分组)
SELECT COUNT(*) 个数, city
FROM departments d, locations l
GROUP BY city;
5.查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
SELECT department_name, d.manager_id, MIN(salary)
FROM departments d, employees d
WHERE d.`department_id` = e.`department_id`
AND commission_pct is NOT NULL
GROUP BY department_name, d.manager_id;
6.查询每个工种的工种名和员工的个数,并且按员工个数降序(添加排序)
SELECT job_title, COUNT(*)
FROM employees e, jobs j
WHERE e.`job_id` = j.`job_id`
GROUP BY job_title
ORDER BY COUNT(*) DESC;
7.查询员工名、部门名和所在的城市(三表连接)
SELECT last_name, department_name, city
FROM employees e, departments d, locations l
WHERE e.`department_id` = d.`department_id`
AND d.`location_id` = l.`location_id`
AND city LIKE '%s%'
ORDER BY department_name DESC;
非等值连接示例
查询员工的工资和工资级别
SELECT salary, grade_level
FROM employees e, job_grades g
WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level` = 'A';
自连接示例
查询员工名和上级的名称
SELECT e.employee_id, e.last_name, m.employee_id, m.last_name
FROM employees e, employees m
WHERE e.`manager_id` = m.`employee_id`;
九、连接查询(SQL1999)
语法:
SELECT 查询列表
FROM 表1 别名 【连接类型】
JOIN 表2 别名
ON 连接条件
【WHERE 筛选条件】
【GROUP BY 分组】
【HAVING 筛选条件】
【ORDER BY 排序列表】
1.内连接(inner):等值连接、非等值连接、自连接
(1)等值连接
① 查询员工名、部门名
SELECT last_name, department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id` = d.`department_id`;
② 查询名字中包含e的员工名和工种名(添加筛选)
SELECT last_name, job_title
FROM employees e
INNER JOIN jobs j
ON e.`job_id` = j.`job_id`
WHERE last_name LIKE '%e%';
③ 查询部门数大于3的城市名和部门个数(添加分组+筛选)
SELECT city, COUNT(*)
FROM departments d
INNER JOIN locations l
ON d.`location_id` = l.`location_id`
GROUP BY city
HAVING COUNT(*) > 3;
④ 查询哪个部门的员工数大于3的部门名和员工个数,并按个数降序(添加排序)
SELECT COUNT(*), department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id` = d.`department_id`
GROUP BY department_name
ORDER BY COUNT(*);
⑤ 查询员工名、部门名、工种名并按照部门名降序
SELECT last_name, department_name, job_title
FROM employees e
INNER JOIN departments d
ON e.`department_id` = d.`department_id`
INNER JOIN jobs j
ON e.`job_id` = j.`job_id`
ORDER BY department_name DESC;
(2)非等值连接
① 查询员工的工资级别
SELECT salary, grade_level
FROM emplyees e
JOIN job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` ADN g.`highest_sal`;
②查询工资级别大于2的个数,并且按工资级别降序
SELECT COUNT(*), grade_level
FROM employees e
JOIN job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`
GROUP BY grade_level
HAVING COUNT(*) > 20
ORDER BY grade_level DESC;
(3)自连接
查询姓名中包含字符k员工的名字,上级的名称
SELECT e.last_name, m.last_name
FROM employees e
JOIN employees m
ON e.`manager_id` = m.`employee_id`
WHERE E.`last_name` LIKE '%k%';
2.外连接
特点:查询结果为主表中的所有记录;如果从表中有和它匹配的,则显示匹配的值,如果从表中没有和它匹配的,则显示null;外连接查询结果=内连接结果+主表中有而从表中没有的记录;左外连接,left join左边的是主表,right join右边的是主表
(1)左外连接(left【outer】)
(2)右外连接(right【outer】)
(3)全外连接(full【outer】)
查询哪个部门没有员工
#左外
SELECT d.*, e.employee_id
FROM departments d
LEFT OUTER JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
#右外
SELECT d.*, e.employee_id
FROM employees e
RIGHT OUTER JOIN departments d
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
十、子查询
含义:出现在其他语句内部的select语句,称为子查询或内查询。
分类:
按查询出现的位置:
- select后面:仅支持标量子查询
- from后面:支持表子查询
- where或having后面:标量子查询、列子查询、行子查询
- exists后面:表子查询
按结果集的行列数不同:
- 标量子查询:结果集只有一行一列
- 列子查询:结果集只有一列多行
- 行子查询:结果集只有一行多列
- 表子查询:一般为多行多列