数据库第二天

第一天补充
ifnull函数
功能:判断某字段或表达式是否为null,如果为null 返回指定值 否则返回原本的值

isnull函数
功能:判断某字段或表达式是否为null,如果是则返回1 不是则返回0


进阶三:排序查询
引入

SELECT * FROM employees;

语法:
SELECT 查询列表
FROM 表
WHERE 筛选条件
ORDER BY 排序列表 【desc|aesc】#desc从高到低 aesc从低到高

特点:
1.asc代表升序 desc是降序 如果不写,默认是升序
2.ORDER BY子句中可以支持单个字段,多个字段,表达式,函数,别名
3.ORDER BY 子句一般是放在查询语句的最后面,但limit子句除外

案例1:查询员工信息,按工资要求从高到低
SELECT * FROM employees ORDER BY salary desc;
SELECT * FROM employees ORDER BY salary;

案列2:查询部门编号>=90的员工信息,按入职时间先后进行排序 添加筛选条件

SELECT * FROM employees
WHERE department_id>=90
ORDER BY hiredate ASC;

案例3:按年龄的高低显示员工的信息和 年龄 按表达式排序顺序

SELECT * ,salary*12*(1+IFNULL(commission_pcT,0)) 年薪
FROM employees
ORDER BY salary*12*(1+IFNULL(commission_pcT,0)) DESC;

案例4:按年薪的高低显示员工的信息和年薪 按别名排序

SELECT * ,salary*12*(1+IFNULL(commission_pcT,0)) 年薪
FROM employees
ORDER BY 年薪 DESC;

案例5:按姓名的长度显示员工的姓名和工资 按函数排序
SELECT LENGTH(last_name) 字节长度,last_name,salary;
FROM employees
ORDER BY LENGTH(last_name);

案例6:查询员工信息 要求按工资排序,再按员工编号排序(按多个字段排序)

SELECT*
FROM employees
ORDER BY salary ASC,employee_id DESC;


进阶四:常见函数

功能:类似于java的方法,将一组逻辑语句封装在方法体中,对外方便暴露方法名
好处:1.隐藏了实现细节 2.提高了代码的可读性
调用:SELECT 函数名(实参列表)|【from 表】;
特点:1.叫什么(函数名)
2.干什么(函数功能)

分类:
1.单行函数
如 concat,length,ifnull等
2.分组函数

功能:做统计使用,又称为统计函数,聚合函数,组函数

常见函数:
一、单行函数
字符函数:
length
concat
substr
instr
trim
upper
lower
lpad
rpad
replace

数学函数:
round
ceil
floor
truncate
mod

日期函数:
now
curdate
curtime
year
month
monthname
day
hour
minute
second
str_to_date
date_format

其他函数:
version
database
user

控制函数
if
case

二、分组函数



一、字符函数
1、length获取参数值的字节个数
SELECT LENGTH('join');
SELECT LENGTH('张三丰hahaha');

SHOW VARIABLES LIKE '%char%'

2.concat拼接字符串

SELECT CONCAT(last_name,'_',first_name) 姓名 FROM employees;

3.upper、lower 大写变小写 小写改大写
SELECT UPPER('join')
SELECT LOWER('joIn')
将姓变大写,名变小写 然后拼接
SELECT CONCAT(UPPER(last_name),LOWER(first_name)) 姓名 FROM employees;

4.substring、substr
注意:索引从1开始
截取从指定索引处后面所有字符
SELECT SUBSTR('李莫愁爱上了路站元',6) out_put;

截取从指定索引处指定字符长度的字符
SELECT SUBSTR('李莫愁爱上了路站元',1,3) out_put;

案列:姓名中首字符大写,其他字符小写然后用_进行拼接,显示出来

SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2)) out_put;
FROM employees;

5.instr 返回子串第一次出现的索引 如果找不到 则返回0

SELECT INSTR('杨不悔爱上了殷六侠','殷六侠') AS out_put;

6.trim

SELECT LENGTH(TRIM(' 张翠山 ')) AS out_put;

SELECT TRIM('a' FROM 'aaaaaaaaaaaaaa张aaaaaaaa翠山aaaaaaaaa') AS out_put;

7.lpad用指定的字符来左填充指定的长度
SELECT LPAD('殷素素',10,'*') AS out_put;

8.rpad用指定的字符来右填充指定的长度
SELECT RPAD('殷素素',10,'*') AS out_put;

9.replace 替换
SELECT REPLACE('周芷若周主任周主任周主任周主任周主任周主任','周主任','张三') AS out_put;

二、数学函数

round 四舍五入
SELECT ROUND(1.55);
SELECT ROUND(1.567,2);#小数点后面保留两位

ceil 向上取整 返回>=该整数的最小整数
SELECT CEIL(1.00)

floor 向下取整 返回<=该整数的最大整数
SELECT FLOOR(-9.9);

truncate 截断
SELECT TRUNCATE(1.65,1);

mod 取余
MOD(a,b):a-a/b*b;
SELECT MOD(10,3);

三、日期函数

now 返回当前系统日期+时间
SELECT NOW()

curdate 返回当前系统日期 不包含时间
SELECT CURDATE();

curtime 返回当前时间,不包含日期
SELECT CURTIME();

可以获取指定的部分,年月日小时分钟秒
SELECT YEAR(NOW()) 年;
SELECT YEAR('1998-1-1') 年;

SELECT YEAR(hiredate) 年 FROM employees;

SELECT MONTH(NOW()) 月;
SELECT MONTHTIME(NOW()) 月;

str_to_date:将日期格式的字符转换成指定格式的日期
STR_TO_DATE('9-13-1999','%m-%d-%Y')

date_format:将日期转换成字符串
DATE_FORMAT('2018/6/6','%Y年%m月%d日');

查询日期为1992-5-3的员工信息
SELECT * FROM employees WHERE hiredate='1992-5-3';

查询又奖金的员工名和入职日期(xx月/xx日 xx年)
SELECT last_name,DATE_FORMAT(hiredate,'%m月/%d日 %Y年') 入职日期
FROM employees;
WHERE commission_pcT IS NOT NULL;

四、其他函数
SELECT VERSION();

SELECT DATEBASE();

SELECT USER();

五、流程控制函数
1.if函数: if else 的效果

SELECT IF('10>5','大','小');

2.case函数使用一:switch case 的效果


case要判断的字段或表达式
when 常量1 then 要显示的值1或语句1;
when 常量1 then 要显示的值2或语句2;
...
else 要显示的值n或语句n;
end

案例:查询员工的工资,要求
部门号=30,显示的工资为1.1倍
部门号=40,显示的工资为1.2倍
部门号=50,显示的工资为1.3倍
其他部门,显示的工资为原工资

SELECT 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 新工资
FROM employees

3.case函数的使用二:类似于 多重if

case
when 条件1 then 要显示的值1或语句1
when 条件1 then 要显示的值1或语句1
...
else 要显示的值n或语句n
end

案例:查询员工的工资情况
如果工资大于20000 显示A级别
如果工资大于15000 显示B级别
如果工资大于10000 显示C级别
否则 显示D级别

SELECT salary
CASE
WHEN salary>20000 THEN 'A'
WHEN salary>15000 THEN 'B'
WHEN salary>10000 THEN 'C'
ELSE 'D'
END AS 工资级别
FROM employees


二、分组函数
功能:做统计使用,又称为统计函数,聚合函数,组函数

分类:
sum 求和、avg求平均、max最大值 min最小值 count计算个数

特点:
1.sum,avg一般用于处理数值类型
max、min、count可以用于处理任何类型
2.以上分组函数忽略null值

3.可以和distinct搭配使用

4.count函数的单独介绍
一般用count(*) 来统计行数

5.和分组函数一同查询的字段要求是group by后的字段 其他的都不行

1.简单的使用
SELECT SUM(salary) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MIN(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT COUNT(salary) FROM employees;

SELECT SUM(salary) 和 , AVG(salary) 平均 , MIN(salary) 最小 , MAX(salary) 最大 , COUNT(salary) 个数
FROM employees;

SELECT SUM(salary) 和 ,ROUND(AVG(salary),2) 平均 , MIN(salary) 最小 , MAX(salary) 最大 , COUNT(salary) 个数
FROM employees;

2、参数支持哪些类型
SELECT SUM(last_name) ,AVG(last_name) FROM employees;
SELECT SUM(hiredate) ,AVG(hiredate) FROM employees;

SELECT MAX(last_name) ,MIN(last_name) FROM employees;
SELECT MAX(hiredate) ,MIN(hiredate) FROM employees;
SELECT COUNT(last_name) FROM employees;
SELECT COUNT(commission_pcT) FROM employees;

3.忽略null
SELECT SUM(commission_pcT) ,AVG (commission_pcT) FROM employees;

SELECT MIN(commission_pcT) ,MIN (commission_pcT) FROM employees;

SELECT COUNT(commission_pcT) FROM employees;

4.和distinct搭配
SELECT SUM(DISTINCT salary),SUM(salary) FROM employees;

SELECT COUNT(DISTINCT salary),COUNT(salary) FROM employees;

5.count函数的详细介绍

SELECT COUNT(salary ) FROM employees;

SELECT COUNT(*) FROM employees;

SELECT COUNT(1) FROM employees;

SELECT COUNT('字段') FROM employees;

效率:
MYISAM存储引擎下,COUNT(*) 的效率高
INNODB存储引擎下,COUNT(*)和COUNT(1)的效率差不多,比COUNT(字段)要高一些


6.和分组函数一同查询的字段有限制

SELECT AVG(salary),employee_id FROM employees;

求两个时间点相差的天数
SELECT DATEDIFF(NOW(),'1998-8-31')

进阶5:分组查询

语法:
select 分组函数,列(要求出现在group by的后面)
from 表
【where 筛选条件】
group by 分组的列表
【order by子句】

注意:
查询列表比较特殊:要求是分组函数和group by后出现的字段

特点:
1.分组查询中的筛选条件分为两类
数据源 位置 关键字
分组前筛选 原始表 group by前面 where
分组后筛选 分组后的结果集 group by后面 having

分组函数做条件肯定是放在having子句中
能用分组前筛选的 就优先考虑分组前筛选

2.group by子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求),表达式或函数(用的较少)
3.可以添加排序(排序放在整个分组查询之后)


引入:查询每个部门的平均工资
SELECT AVG(salary) FROM employees;


简单的分组查询:
案列1:查询每个工种的最高工资
SELECT MAX(salary),job_id
FROM employees
group by job_id;

案例2:查询每个位置上的部门个数
SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;

添加筛选条件
案例1:查询邮箱中包含a字符的,每个部门的平均工资

SELECT AVG(salary),department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;

案例2:查询有奖金的每个领导手下员工的最高工资
SELECT MAX(salary),manager_id
FROM employees
WHERE commission_pcT IS NOT NULL
GROUP BY manager_id;

添加分组后的筛选条件

案例1:查询哪个部门的员工数>2

1.查询每个部门的员工个数
SELECT count(*),department_id
FROM employees
GROUP BY department_id;

2.根据1的结果进行筛选,查询哪个部门的员工个数>2

SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2

案例2:每个工种有奖金的员工的最高工资>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;

案列3:查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资

1.查询每个领导手下的员工固定最低工资
SELECT MIN(salary),manager_id
FROM employees
GROUP BY manager_id

2.添加筛选条件:编号>102 最低工资大于5000

SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000;

按表达式或函数分组

案例:按员工姓名的长度分钟,查询每一组的员工数,筛选员工个数>5的有哪些

1.查询每个长度的员工个数

SELECT COUNT(*),LENGTH(last_name) len_name
FROM employees
GROUP BY LENGTH(last_name);


2.添加筛选条件

SELECT COUNT(*),LENGTH(last_name) len_name
FROM employees
GROUP BY LENGTH(last_name)
HAVING COUNT(*)>5;

按多个字段分组

案例:查询每个部门每个工种的员工的平均工资

SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id;


添加排序
案例:查询每个部门每个工种的员工的平均工资,并按平均工资的高低显示

SELECT AVG(salary),department_id,job_id
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id,job_id
HAVING AVG(salary)>10000
ORDER BY AVG(salary) DESC;

进阶6:连接查询

含义:又称多表查询 当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积:表1 有m行 表2 有n行 结果=m*n行

发生原因:没有有效的连接条件
如何避免:添加有效的连接条件

分类:
按年代分类:
sql92标准:仅仅支持内连接
sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接

按功能分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
交叉连接:


SELECT * FROM beauty;
SELECT * FROM boys;

SELECT NAME,boyName FROM boys,beauty
WHERE beauty.boyfriend_id=boys.id;

一、sql92标准
1.等值连接

多表等值连接的结果为多表的交集部分
n表连接,至少需要n-1个连接条件
多表的顺序没有要求
一般需要为表名取别名
可以搭配前面介绍的所有子句使用,比如排序、分组筛选

案例1:查询女神名和对应的男神名
SELECT NAME,boyName
FROM boys,beauty
WHERE beauty.boyfriend_id=boys.id;

案例2:查询员工名和对应的部门名

SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id=departments.department_id;

2.为表起别名
提高语言的简洁度
区分多个重名字段
注意:如果为表起了别名,则查询字段就不能使用原来的表名去限定了

查询员工名、工种号、工种名

SELECT e.last_name,e.job_id,j.job_title
FROM employees e,jobs j
WHERE e.job_id=j.job_id;

3.两个表的顺序是否可以调换

查询员工名、工种号、工种名

SELECT e.last_name,e.job_id,j.job_title
FROM employees e,jobs j
WHERE e.job_id=j.job_id;

4.可以加筛选

案例:查询有奖金的员工名、部门名

SELECT last_name,department_name,commission_pcT
FROM employees e,departments d
WHERE e.department_id=e.department_id
AND e.commission_pcT IS NOT NULL;

案例2:查询城市名中第二个字符为o的对应的部门名和城市名

SELECT department_name,city
FROM departments d,locations l
WHERE d.location_id =l.location_id;
AND city LIKE '_o%';

5.可以加分组

案例1:查询每个城市的部门个数

SELECT COUNT(*) 个数,city
FROM departments d,locations l
WHERE d.location_id=l.location_id
GROUP BY city;

案例2:查询有奖金的每个部门名和部门的领导编号和该部门的最低工资
SELECT department_name,d.manager_id,MIN(salary)
FROM departments d,employees e
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;


2.非等值连接

案例1:查询员的工资和工资级别

SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal;

SELECT salary employee_id FROM employees;
SELECT * FROM job_grades;

3.自连接

案例:查询 员工名 和上级名称

SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.manager_id=m.manager_id

原文地址:https://www.cnblogs.com/liugangjiayou/p/11668710.html