1. 基础查询
1.1 基础查询概述
- 基础查询的基本语法为:select 查询列表 form 表名;
- 查询的结果集是一个虚拟表,类似与Java中的System.out.println()
- 进行基础查询的内容可以是:字段、表达式、常量、函数等
1.2 使用方法
-
查询常量
SELECT 100;
-
查询表达式
SELECT 100%3;
-
查询单个字段
SELECT `last_name` FROM `employess`;
-
查询多个字段
SELECT `last_name`,`email`,`employee_id` FROM employess;
-
查询所有字段
SELECT * FROM employees;
-
查询函数
SELECT DATABASE(); SELECT VERSION(); SELECT USER();
-
起别名
#方式一:使用as关键字 SELECT USER() AS 用户名; SELECT USER() AS '用户名'; SELECT USER() AS "用户名"; SELECT last_name AS "姓 名" FROM employess; #方式二:使用空格 SELECT USER() 用户名; SELECT USER() '用户名'; SELECT USER() "用户名"; #当使用空格时必须用引号 SELECT last_name "姓 名" FROM employess;
-
拼接不同的列
#使用拼接函数concat SELECT CONCAT(first_name,last_name) AS "姓名" FROM employess;
-
去除重复数据
#使用去重函数distinct SELECT DISTINCT department_id FROM employess;
-
查看表结构
#方式一 DESC employees; #方式二 SHOW COLUMNS FROM emloyees;
-
判断是否为空
#ifnull(表达式1,表达式2) /* 表达式1:可能为null的字段或表达式 表达式2:如果表达式1为null,则最终显示的值 */ SELECT IFNULL(commission_pct,'') FROM employees;
2. 条件查询
2.1 条件查询概述
- 条件查询的语法为:select 查询列表 from 表名 where 筛选条件;
- 执行顺序为:form语句、where语句、select语句
- 条件查询有三种方式:
- 按关系表达式筛选:<、>、=、<=、>=、<>(不等于)
- 按逻辑表达式筛选:and(与)、or(或)、not(非)
- 模糊查询:like、in、between and、is null
2.2 使用方法
按关系表达式筛选
#案例1:查询部门编号不是100的员工信息
SELECT *
FROM employees
WHERE department_id <> 100;
#案例二:查询工资<15000的员工姓名、工资
SELECT last_name,salary
FROM employees
WHERE salary < 15000;
按逻辑表达式筛选
#案例一:查询部门编号不是50-100之间员工姓名、部门编号、邮箱
SELECT last_name,department_id,email
FROM employees
WHERE department_id>100 OR department_id<50;
#案例二:查询奖金率>0.03或者 员工编号在60-100之间的员工信心
SELECT *
FROM employees
WHERE commission_pct>0.03 OR (employee_id>=60 AND employee_id<=100);
模糊查询
- like:一般与通配符搭配使用,对字符型数据进行部分匹配查询,常见的通配符:
- '_'任意单个字符
- '%'任意多个字符
#案例一:查询姓名中包含字符a的员工信息
SELECT *
FROM employees
WHERE last_name LIKE '%a%';
#案例二:查询姓名中最后一个字符为a的员工信息
SELECT *
FROM employees
WHERE last_name LIKE '%a';
#案例三:查询姓名中第三个字符为a的员工信息
SELECT *
FROM employees
WHERE last_name LIKE '__a%';
#案例四:查询姓名中第二个字符为_的员工信息
SELECT *
FROM employees
WHERE last_name LIKE '_\_%';
SELECT *
FROM employees
#设置任意字符为转义符号
WHERE last_name LIKE '_$_%' ESCAPE '$';
- in:查询某字段的值是否属于指定的列表内
#案例一:查询部门编号是30、50、90的员工名、部门编号
SELECT last_name,department_id
FROM employees
WHERE department_id IN(30,50,90);
#案例二:查询公众编号不是SH_CLERK或IT_PROG的员工信息
SELECT *
FROM employees
WHERE job_id NOT IN ('SH_CLERK','IT_PROG');
- between and:判断某个字段的值是否介于xx之间
#案例一:查询部门编号是30-90之间的部门编号、员工姓名
SELECT department_id ,last_name
FROM employees
WHERE department_id BETWEEN 30 AND 90;
#案例二:查询年薪不是10000-20000之间的员工姓名、工资、年薪
SELECT last_name,salary,salary*12*(1+IFNULL(commission_pct,0))
FROM employees
WHERE salary*12*(1+IFNULL(commission_pct,0)) NOT BETWEEN 10000 AND 20000;
- is null:判断值是否null
- =:只能判断普通内容
- IS:只能判断NULL值
- <=>:安全等于,既能判断普通内容,又能判断NULL值
#案例一:查询没有奖金的员工信息
SELECT *
FROM employees
WHERE commission_pct IS NULL;
#案例二:查询有奖金的员工信息
SELECT *
FROM employees
WHERE commission_pct IS NOT NULL;
3. 排序查询
3.1 排序查询概述
- 条件查询的语法:select 查询列表 from 表名 where 筛选条件(可有可无) order by 排序列表
- 执行顺序:from子句、where子句、select子句、order by子句
- 特点:
- 排序列表可以是单个字段、多个字段、表达式、函数、列数、以及以上组合
- 升序,通过asc,默认行为
- 降序,通过desc
3.2 使用方法
- 按单个字段查询
#案例:将员工编号>120的员工信息进行工资的升序
SELECT *
FROM employees
WHERE employee_id >120
ORDER BY salary;
- 按表达式排序
#案例:对有奖金的员工,按年薪降序
#也可以将年薪表达式起别名,直接在表达式后添加别名
SELECT salary*12*(1+IFNULL(commission_pct,0))
FROM employees
WHERE commission_pct
ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
- 按函数的结果排序
#案例:按姓名的字数长度进行升序
SELECT last_name
FROM employees
ORDER BY LENGTH(last_name);
- 按多个字段排序
#案例:查询员工姓名、工资、部门编号,先按工资升序,再按部门编号降序
SELECT last_name,salary,department_id
FROM employees
ORDER BY salary ASC,department_id DESC;
- 按列数排序
#案例:按第二列排序
SELECT *
FROM employees
ORDER BY 2
4. 常见函数
4.1 字符函数
1. CONCAT 拼接字符
SELECT CONCAT('hello',first_name,last_name) FROM employees;
2. LENGTH 获取字节长度
SELECT LENGTH('hello,张三');
3. CHAR_LENGTH 获取字符长度
SELECT CHAR_LENGTH('hello,张三');
4. SUBSTR 截取子串
/*
注意:起始索引从1开始
substr(str,起始索引,截取的字符长度)
substr(str,起始索引) 将后面的字符串都截取
*/
SELECT SUBSTR('helloworld!',1,3);
SELECT SUBSTR('helloworld!',6);
5. INSTR 获取字符第一次出现的位置
SELECT INSTR('helloworldllold','ll')
6. TRIM 去除前后指定的字符,默认为空格
SELECT TRIM(" hello world ");
SELECT TRIM('x' FROM 'xxxxhelloxxxworldxxxx');
7. LPAD/RPAD 坐填充/右填充
SELECT LPAD('张三',10,'a'); #填充完毕后一共10个字符
SELECT RPAD('张三',10,'a');
8. UPPER/LOWER 变大写/变小写
SELECT UPPER('abc');
SELECT LOWER('ABC');
9. STRCMP 比较两个字符大小
#第一个字符大,返回1;第一个小,返回-1;相等,返回0
SELECT STRCMP('abc','aaa')
4.2 数学函数
1. ABS 绝对值
SELECT ABS(-12);
2. CEIL 向上取整 返回>=该参数的最小整数
SELECT CEIL(0.09);
3. FLOOR 向下取整 返回<=该参数的最大整数
SELECT FLOOR(0.09)
4. ROUND 四舍五入
SELECT ROUND(3.14);
5. TRUNCATE 截断
SELECT TRUNCATE(3.14);
6. MOD 取余
SELECT MOD(10,3);
SELECT 10%3;
4.3 日期函数
1. NOW 当前日期和时间
SELECT NOW();
2. CURDATE 当前日期
SELECT CURDATE();
3. CURTIME 当前时间
SELECT CURTIME();
4. DATEDIFF 日期之差
SELECT DATEDIFF('2020-8-19','2000-6-23');
5. DATE_FORMAT 将日期转换为固定格式
SELECT DATE_FORMAT('2000-6-23','%Y年%m月%d日 %H时%i分%s秒');
6. STR_TO_DATE 按指定格式解析字符串为日期类型
SELECT STR_TO_DATE('6/23 2000','%m/%d %Y');
4.4 流程控制函数
1. IF 函数
SELECT IF(100>9,'好','坏');
#案例:如果有奖金,则显示最终奖金,如果无,则显示0
SELECT IF(commission_pct IS NULL,0,salary*12*commission_pct)
FROM employees;
2. CASE 函数
情况1:类似switch语句,可以实现等值判断
CASE 表达式
WHEN 值1 THEN 结果1
WHEN 值2 THEN 结果2
...
ELSE 结果n
END
SELECT department_id,salary,
CASE department_id
WHEN 30 THEN salary*2
WHEN 50 THEN salary*3
WHEN 60 THEN salary*4
ELSE salary
END
情况2:类似多重IF语句,实现区间判断
CASE
WHEN 条件1 THEN 结果1
WHEN 条件2 THEN 结果2
...
ELSE 结果n
END
SELECT salary,
CASE
WHEN salary>20000 THEN 'A'
WHEN salary>15000 THEN 'B'
WHEN salary>10000 THEN 'C'
ELSE 'D'
END grade
FROM employees;
5. 分组查询
5.1 分组函数
分组函数往往用于实现将一组数据进行统计计算,最终得到一个值,又称为聚合函数或统计函数
分组函数有:
- sum(字段名):求和
- avg(字段名):求平均值
- max(字段名):求最大值
- min(字段名):求最小值
- count(字段名):计算非空字段值的个数
#案例1:查询员工信息表中,所有员工的工资和、工资平均值、
#最低工资、最高工资、有工资的个数
SELECT SUM(salary),AVG(salary),MIN(salary),MAX(salary),COUNT(salary)
FROM employees;
#count补充说明
#统计结果集的行数,推荐使用count(*)
SELECT COUNT(*) FROM employees;
5.2 分组查询
- 分组查询语法:
- select 查询列表,⑤
- from 表名,①
- where 筛选条件,②
- group by 分组列表,③
- having 分组后筛选,④
- order by 排序列表;,⑥
- 分组查询特点:
- 查询列表是分组函数和被分组的字段
- 分组前筛选放入where后,带有分组函数的筛选(分组后筛选)放入having中
#案例1:查询每个工种的员工的平均工资
SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;
#案例2:查询每个领导手下有奖金的员工的平均工资
SELECT AVG(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;
#案例3:领导编号>102,每个领导手下的最低工资大于5000的最低工资
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000
#案例4:查询没有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序
SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NULL
GROUP BY job_id
HAVING MAX(salary)>6000
ORDER BY MAX(salary) ASC;
#案例5:查询每个工种每个部门的最低工资,并按最低工资降序
SELECT MIN(salary),job_id,department_id
FROM employees
GROUP BY job_id,department_id;
6. 连接查询
6.1 连接查询概述
若一个查询同时涉及两个以上的表,则称为连接查询
连接查询是关系数据库中最主要的查询,包括:
- 等值连接查询
- 自然连接查询:自然连接是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是同名的属性组,并且在结果中把重复的属性列去掉
- 非等值连接查询
- 自身连接查询:连接操作不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为表的自身连接
- 外连接查询:与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行
- 复合条件链接查询:连接操作除了可以是两表连接,一个表与自身连接外,还可以是两个以上的表进行连接
6.2 使用方法
等值与非等值连接查询
等值连接语法:
- select 查询列表,⑥
- from 表明1,表明2,表明3,...,①
- where 等值连接的连接条件,②
- and 筛选条件,③
- group by 分组列表,④
- having 分组后筛选,⑤
- order by 排序列表,⑦
等值连接特点:
- 多表等值连接的结果为多表的交集部分
- 多表的顺序没有要求
- 一般要为表起别名
当连接运算符为=时,称为等值连接,使用其他运算符称为非等值连接
#案例1:查询员工名和部门
#起别名后select语句只允许用别名,与执行顺序相关
SELECT e.`last_name`,d.`department_name`
FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`;
#案例2:查询部门编号>100的部门名和所在的城市名
SELECT department_id,city
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id`
AND d.`department_id`>100;
#案例3:查询每个城市的部门个数
SELECT COUNT(*),l.`city`
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id`
GROUP BY l.`city`;
#案例4:查询每个工种的工种名和员工个数,并且按员工个数降序
SELECT job_title,COUNT(*)
FROM employees e,jobs j
WHERE e.`job_id`=j.`job_id`
GROUP BY job_title
ORDER BY COUNT(*) DESC;
#案例5:查询员工名、部门名和所在城市
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`;
7. 子查询
7.1 子查询概述
当一个查询语句中又嵌套了另一个完整的select语句,则被嵌套的select语句称为子查询或内查询,外面的select语句称为主查询或外查询
子查询不一定必须出现在select语句内部,只是出现在select语句内部的时候比较多
按子查询出现位置进行分类:
- select后面:要求子查询结果为单行单列(标量子查询)
- form后面:子查询的结果可以多行多列
- where或having后面:子查询的结果必须为单列,分为单行子查询和多行子查询
- exist后面:子查询结果必须为单列(相关子查询)
子查询特点:
- 子查询放在条件中,必须要求放在条件的右侧
- 子查询一般放在小括号中
- 子查询的执行顺序优先于主查询
- 单行子查询对应单行操作符:>、<、>=、<=、=、<>
- 多行子查询对应了多行操作符:any/some、all、in
7.2 使用方法
子查询放在where或having后面
- 单行子查询
#查询和Zlotkey相同部门的员工姓名和工资
SELECT last_name,salary
FROM employees
WHERE department_id = (
SELECT department_id
FROM employees
WHERE last_name = 'Zlotkey'
);
#查询工资比公司平均工资高的员工的员工号,姓名和工资
SELECT employee_id,last_name,salary
FROM employees
WHERE salary >(
SELECT AVG(salary)
FROM employees
);
- 多行子查询
in:判断某字段是否在指定列表内
any/some:判断某字段的值是否满足其中任意一个
all:判断某字段的值是否满足里面所有的
#查询location_id是1400或1700的部门中的所有员工姓名
SELECT last_name
FROM employees
WHERE department_id IN (
SELECT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
#返回其他部门中比job_id为'IT_PROG'部门任一工资低的员工的
#员工号、姓名、job_id以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary < ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
);
#返回其他部门中比job_id为'IT_PROG'部门所有工资低的员工的
#员工号、姓名、job_id以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary < ALL(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
);
子查询放在其他关键词后面
- 放在select后面
#查询部门编号是50的员工个数
SELECT(
SELECT COUNT(*)
FROM employees
WHERE department_id = 50
);
- 放在from后面
#查询每个部门的平均工资的工资级别
SELECT dep_ag.department_id,dep_ag.ag,g.grade
FROM sal_grade g
JOIN(
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) dep_ag ON dep_ag.ag BETWEEN g.min_salary AND g.max_salary;
- 放在exist后面
# 查询有无名字叫'张三丰'的员工信息
SELECT EXISTS(
SELECT *
FROM employees
WHERE last_name = '张三丰'
) 有无;
8. 分页查询
8.1 分页查询概述
当页面上的数据,一页显示不全,则需要分页显示
分页查询的sql命令请求数据库服务器——>服务器响应查询到的多条数据——>显示在前台页面
分页查询语法:
- select 查询列表,⑤
- from 表明1,表明2,表明3,...,①
- where 等值连接的连接条件,②
- group by 分组列表,③
- having 分组后筛选,④
- order by 排序列表,⑥
- limit 起始条目索引,显示的条目数,⑦
分页查询特点:
- 起始条目索引从0开始,如果不写,默认为0
- 参数一:起始条目数,参数二:需要显示的条目数
8.2 使用方法
#查询员工信息表的前5条
#两者完全相同
SELECT * FROM employees LIMIT 0,5;
SELECT * FROM employees LIMIT 5;
#查询有奖金的,且工资较高的第11名到第20名
SELECT *
FROM employees
WHERE commission_pct IS NOT NULL
ORDER BY salary DESC
LIMIT 10,10;
假如要显示的页数是page,每页显示的条目数为size,则limt (page-1)size,size;*
9. union联合查询
当查询结果来自于多张表,但多张表之间没有关联,这个时候往往使用联合查询,也称为union查询
联合查询语法:
SELECT 查询列表 FROM 表1 WHERE 筛选条件……
UNION
SELECT 查询列表 FROM 表1 WHERE 筛选条件……
#查询所有国家的年龄>20岁的用户信息
SELECT * FROM China WHERE age>20 UNION
SELECT * FROM USA WHERE age>20
要求多条查询语句的多条列数必须一致,且不同表的每一列必须对应上
union自动去重,在union后加all会取消去重