SQL-SELECT(3)多表查询,分组函数,子查询

2021.10.28

多表查询

课件中主要表结构:
在这里插入图片描述

select employee_id,department_id,department_name
from employees,departments

由于department_id字段同时存在于两个表中,该查询方式会导致将两表中所有信息组合显示得到length(a)*length(b)大小的数据量,并不符合我们需要查询的信息,该错误称为笛卡尔集错误。

为避免该错误产生,需要加入过滤条件,即where

等值连接

select e.employee_id,e.department_id,d.department_name --第1,3项中的前缀可以省略
from employees e,departments d
where e.department_id = d.department_id

需要多个表可以直接添加连接条件,n个表需要至少n-1个连接条件

非等值连接

直接使用比较运算符或between等进行运算

select employee_id,last_name,salary,grade_level
from employees e,job_grades j
where e.salary between j.lowest_sal and j.highest_sal

外连接

上述方式称为内连接,不包含两表中不匹配的内容,而外连接可以

select e.employee_id,e.department_id,d.department_name --第1,3项中的前缀可以省略
from employees e,departments d
where e.department_id = d.department_id(+)

返回包含左表中的不匹配内容,右表则将加号添加在左侧,不允许两侧均有

cross join & natural join

cross join同样会产生笛卡尔集错误
natural join能不需要限定表名,自动识别表中相等的所有字段的筛选,即存在多条一致列名时,返回各个列均相等的值

select employee_id,department_id,department_name
from employees natural join departments

join using

select employee_id,department_id,department_name
from employees join departments
using(department_id)
--选取指定列进行连接

缺点:列名必须一致,不能实现列名不一致的连接

join on

select employee_id,d.department_id,department_name,city
from employees e join departments d
on e.department_id = d.department_id
join location l
on d.location_id = l.location_id
--选取指定列进行连接,可以避免上述缺点

left/right/full outer join

在join前添加,达到与上述外连接一致的效果,outer可以省略
full outer join实现外连接中不能实现的左右表均显示

自连接

实现在同一个表中进行连接操作,将单个表命名为两个表

select emp.last_name,manager.last_name,manager.salary,manager.email
from employees emp,employees manager
where emp.manager_id = manager.employee_id and lower(emp.last_name) = 'chen'
--查询公司中员工'chen'的manager信息

分组函数

属于多行函数
AVG
COUNT
MAX
MIN
STDDEV:标准差
SUM

select avg(salary),max(salary),min(salary),sum(salary)
from employees

其中AVG和SUM函数不能对日期/字符进行运算
COUNT函数只计算不为空的值的个数,并且参数若填入不是列名,则输出总共多少条数据count(1) = count(2)
AVG中使用sum/count,因此无法严格计算平均值,只能计算包含的平均值
需要严格计算平均值时可以利用

select sum(salary)/count(nvl(salary,0))--nvl:将空值进行转化

利用distinct关键字可以返回非重复列select count(distinct salary) from employees

group by

将需要得到的值按照列进行分组

select department_id,avg(salary)
from employees
group by department_id
--计算相同部门中各自的平均薪水

在这里插入图片描述

select department_id,avg(salary)
from employees
where department_id in (40,60,80)
group by department_id
--计算在40,60,80部门中各自的平均薪水

注意,where关键字必须在from后出现

group by还可以实现多个分组:

select department_id,job_id,avg(salary)
from employees
group by department_id,job_id--不能删除,因为AVG输出会只有一个
--计算不同部门中不同工作各自的平均薪水

having子句

where子句中不能使用组函数

where avg(salary>100)

需要使用having,having放在group by前后均可

having avg(salary>100)

组函数可以嵌套:max(avg(salary))

子查询

即嵌套查询

select last_name
from employees
where salary > (select salary
                from employees
                where last_name = 'Tom')
--查询比tom工资更高的员工     

子查询(内查询)优先执行,结果返回到父查询(外查询)中作为条件

单行子查询

select last_name,job_id,salary
from employees
where job_id = (
                select job_id
                from employees
                where employee_id = 141
                )
and salary > (
              select salary
              from employees
              where employees_id = 143
              )
--查询大于143号员工薪水的,和141号员工工作一致的员工                        

若子查询返回空值,则主查询由于无法满足条件,也返回空值

多行子查询

(NOT) IN:(不)等于列表(子查询返回值)中的一个
ANY:和列表中任意一个比较满足即可
ALL:必须与列表中所有值比较

select a
from list
where a < any (select...)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值