SQL学习之常见函数和连接查询
常见函数:
概念:类似于Java中的方法,将一组逻辑语句封装在方法体中,对外暴露方法名
好处:1、隐藏了实现细节,2、提高代码的重用性
调用:select 函数名()
特点:1、叫什么(函数名), 2、干什么(函数功能)
分类:
-
单行函数
如cancat、length、ifnull
-
分组函数
功能:做统计使用,又称为统计函数
单行函数:
一、字符函数
-
length 获取参数的字节个数
SELECT LENGTH('john'); SELECT LENGTH('张三丰hahahha') -
concet 拼接字符串
SELECT CONCAT(last_name,'_',first_name) FROM employees; -
upper、lower
SELECT UPPER('john') SELECT LOWER('john')#示例 :将姓变大写,名变小写,然后拼接 SELECT CONCAT(UPPER(last_name),LOWER(first_name)) 姓名 FROM employees; -
substr、substring 截取字符串子串
注意:索引从1开始#截取从指定后面所有字符 SELECT SUBSTR('李莫愁爱上了陆展元',7) out_put; #截取从指定索引处指定字符长度的字符 SELECT SUBSTR('李莫愁爱上了路展元',1,3) out_put; -
instr 返回子串第一次出现的索引,如果找不到返回0
SELECT INSTR('杨不悔爱上了殷六侠','殷六侠') AS out_put FROM employees; -
trim
SELECT LENGTH(TRIM('张翠山')) AS out_put; SELECT TRIM('a' FROM 'aaaaaaaaaaaaaaaaa张aaaaaaaaaa翠山aaaaaaaaaaaaa') AS out_put; -
lpad 用指定的字符实现左填充指定长度
SELECT LPAD('殷素素',10,'*') AS out_put -
rpad 用指定的字符实现右填充指定长度
SELECT RPAD('殷素素',12,'ab') AS out_put -
replace 替换
SELECT REPLACE('周芷若周芷若周芷若周芷若周芷若张无忌爱上了周芷若','周芷若','赵敏') AS out_out
二、数学函数
-
round 四舍五入
SELECT ROUND(-1.65); -
ceil 向上取整,返回>=该参数的最小整数
SELECT CEIL(-1.02); -
floor 向下取整,返回<=该参数的最大整数
SELECT FLOOR(-9.99); -
truncate 截断
SELECT TRUNCATE(1.699999,1); -
mod 取余
SELECT MOD(10,3); #SELECT 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 MONMTHANME(NOW()) 以英文的形式返回月;
四、其他函数
VERSION();返回当前数据库版本
DATABASE();当前打开的数据库
USER();当前用户
password(‘字符’):返回该字符的密码形式
MD5(‘字符’):返回该字符的md5加密形式
五、流程控制函数
-
if函数 :if else 的效果
SELECT IF (10<5.'大','小'); SELECT last_name,commission_pct,IF(commission-pct IS NULL,'没奖金,呵呵','有奖金,嘻嘻') 备注 FROM employees; -
case函数的使用一:switch case 的效果
#mysql中 case 要判断的变量或表达式 when 常量1 then 要显示的值1或语句1; when 常量1 then 要显示的值1或语句1; ... else 要显示的值n或语句n; end -
case函数的使用二:类似于多重if
#mysql中 case when 条件1 then 要显示的值1或语句1 when 条件2 then 要显示的值2或语句2 。。。 else 要显示的值n或语句n end
分组函数
分组函数
功能:用作统计使用,又称为聚合函数或统计函数或组函数
分类:
sum求和、avg平均值、max最大值、min最小值、count计算个数
特点:
-
sum、avg 一般用于处理数值型
max、min、count可以处理任何类型
-
以上分组函数都忽略null值
-
可以和distinct搭配实现去重的运算
-
count函数可以单独使用
-
和分组函数一同查询的字段有限制
分组查询
语法
select分组函数,列(要求出现子啊group by的后面)
from表
【where 筛选信息】
group by 分组的列表
【order by 子句】
注意:
查询列表必须特殊,要求时分组函数和group by后出现的字段
特点:
-
分组擦汗寻重点筛选条件分为两种:
数据源 位置 关键字 分组后筛选 原始表 group by子句的前面 where 分组后筛选 分组后的结果集 group by子句的后面 having - 分组函数做条件肯定是放在having子句中
- 能用分组请筛选,就优先考虑使用分组前筛选
-
group by 子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求),表达
-
也可以添加排序(排序放在整个分组查询的最后)
-
简单的分组查询
#案例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 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 comission_pct IS NOT NULL GROUP BY job_id #2、根据1、结果继续筛选,最高工资>12000 SELECT MAX(salary),job_id FROM employees WHERE comission_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 SELECT MIN(salary),manager_id FROM employees WHERE manager_id >102 GROUP BY manager_id; #3、添加筛选条件:工资》5000 SELECT MIN(salary),manager_id FROM employees WHERE manager_id >102 GROUP BY manager_id HAVING MIN(salary)>5000; -
按多个字段分组
#案例:查询每个部门每个工种的员工的平均工资 SELECT AVG(salary),department_id,job_id FROM employees GROUP BY job_id,department_id;#添加排序 #案例:擦汗寻每个部门的每个工种的员工的平均工资,并且按平均工资的高低显示SELECT AVG(salary),department_id,job_id FROM employees GROUP BY job_id,department_id ORDER BY AVG(salary) DESC;
连接查询
含义:又称多表查询,当我们要查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1有m行,表2有n行,结果=m*n行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
分类:
- 按年代分类
- sql192标准:仅仅只支持内连接
- sql199标准【推荐】:支持内连接+外连接(右外连接+左外连接)+交叉连接
- 按功能分类:
- 内连接:
- 等值连接
- 非等值连接
- 自链接
- 外连接:
- 左外连接:保留左表的所有记录,同时匹配右表中满足连接条件(
ON子句)的记录。 - 右外连接:保留右表的所有记录,同时匹配左表中满足连接条件的记录。
- 全外连接(mysql不能使用):返回两个表中所有匹配和不匹配的记录
- 左外连接:保留左表的所有记录,同时匹配右表中满足连接条件(
- 交叉连接:
- 内连接:
一、sql192标准
等值连接
-
语法:
select 查询列表 from 表1,表2 where 表1.key=表2.key [and 筛选条件] 【group by 分组字段】 【order by 排序字段】 -
特点:
1.一般为表起别名 2.多表的顺序可以调换 3.n表连接至少需要n-1个连接条件 4.等值连接的结果是多表的交集部分
#案例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;
-
为表起别名
-
提高了语句的简洁度
-
区分多个重名的字段
-
注意:如果为表起了别名,则查询的字段就不能使用原来的表名去限定
#查询员工名、工种号、工种名
-
-
两个表达顺序是否可以调换(无所谓)
-
可以加筛选条件
-
可以加分组
#查询每个城市的部门个数 SELECT COUNT(*) 个数,city FROM departments d,loations 1 GROUP BY city; #案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资 SELECT department_nam,manager_id,MIN(salary) FROM departments d,employees e WHERE d.department_id=e.department_id AND commoission_pct IS NOT NULL GROUP BY department_name, d.manager_id; -
可以加排序
#案例:查询每个工种的工种名和员工的个数,并且按员工个数降序 SELECT job_title,COUNT(*) FROM employees,jobs j WHERE e.job_id = j.job_id GROUP BY job_title ORDER BY COUNT(*) DESC: -
可以实现三表连接

非等值连接
-
定义:是指在JOIN的链接条件中,不用等号(),而是使用其他比较运算符(例如:
>、<、>=、<=、!=、BETWEEN)来匹配两行表的行 -
语法:
select 查询列表 from 表1,表2 where 非等值的连接条件 [and 筛选条件] 【group by 分组字段】 【having 分组后的筛选】 【order by 排序字段】
自链接
1.语法:
select 查询列表
from 表 别名1,表 别名2
where 等值的连接条件
[and 筛选条件]
【group by 分组字段】
【having 分组后的筛选】
【order by 排序字段】
二、sql99语法
语法:
select 查询列表
from 表1 别名 【连接类型】
join 表2 别名
on 连接条件
【where 筛选条件】
【group by 分组】
【having 分组后筛选】
【order by 排序列表】
内连接:inner
-
语法:
select 查询列表 from 表1 别名 【连接类型】 inner join 表2 别名 on 连接条件 【where 筛选条件】 【group by 分组】 【having 分组后筛选】 【order by 排序列表】 -
分类:
-
等值连接
-
案例
-
特点:
- 添加排序,分组,筛选
- inner可以省略
- 筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读
- inner join连接和sql92语法中的等值连接效果是一样的,都是查询到表的交集
-
-
非等值连接
#查询员工的工资级别 select salary,grade_level from employees e join job_grades g on e.salary between g.lowest_sal and g.highest_sal#查询工资级别的个数>2,并且按工资级别降序 select salary,garde_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; -
自连接
#查询员工的名字、上级的名字 select e.last_name,m.last_name from employees e join employees m on e.manager_id = m.employee_id
-
-
特点:
- 表的顺序可以调换
- 内连接的结果=多表的交集
- n表连接至少需要n-1个连接条件
外连接:outer
-
应用场景:用于查询一个表中有,另一个表没有的记录
-
语法:
select 查询列表 from 表1 别名 【连接类型】 left|right|left join 表2 别名 on 连接条件 【where 筛选条件】 【group by 分组】 【having 分组后筛选】 【order by 排序列表】 -
特点:
-
外连接的查询结果为主表中的所有记录
如果从表中有和它匹配的,则显示匹配的值
如果从表中没有和它匹配的,则显示null
外连接查询结果=内连接结果+主表中有而从表中没有的记录
-
左外连接:left join 左边的是主表
右外连接:right join 右边的是主表
-
左外和右外交换两个表的顺序,可以实现同样的效果
-
查询结果一般用于查询出来交集部分的剩余的不匹配的行
-
-
分类:
-
左外:left
#案例:查询哪个部门没有员工 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-
右外:right
-
全外:full
-
-
SELECT b.,bo.
FROM beauty b
FULL OUTER JOIN boys bo
ON b.boyfriend_id =bo.id
5. 区别:## 交叉连接:cross语法:```sql
select 查询列表
from 表1 别名
cross join 表2 别名;
特点:
类似于笛卡尔乘积
案例
SELECT b.*,bo.*
FROM beauty b
cross join boys bo
三、总结:
sql192和sql99
功能:sql99支持较多
可读性:sql99实现连接条件和筛选条件的分离
案例:
#一、查询编号 > 3 的女神的男朋友信息,如果有则列出详细,如果没有,用 null 填充
SELECT b.id,b.name,bo.*
FROM beauty b
LEFT OUTER JOIN boys bo
ON b.boyfriend_id=bo.id
WHERE b.id>3
ORDER BY bo.id;#二、查询哪个城市没有部门
SELECT city
FROM departments d
RIGHT OUTER JOIN locations l
ON d.location_id = l.location_id
WHERE d.department_id IS NULL;#三、查询部门名为 SAL 或 IT 的员工信息
SELECT e.*,d.department_name
FROM departments d
LEFT JOIN employees e
ON d.department_id = e.department_id
WHERE d.department_name IN ('SAL','IT')SELECT * FROM departments d
WHERE d.department_name IN ('SAL','IT')