SQL(Oracle)进阶学习

SQL语法学习

  • "自链接":其实时一种概念,某个table和自己本身链接。
select worker.last_name || 'works for'|| manager.last_name
FROM   employees worker, employees manager
      WHERE worker.manager_id = manager.employee_id ;

多表关联查询

  • 交叉链接:相当于没有条件的多表关联查询,结果是个笛卡尔乘积。
  • 全外链接
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
FULL OUTER JOIN departments d
ON (e.department_id = d.department_id) ;

分组计算函数和group by字句注意点

  • SELECT 查询语句中同时选择分组计算函数表达式和其他独立字段时 ,其他字段必须出现在Group By 子 句中,否则不合法。
  • 不能在Where 条件中使用分组计算函数表达式,当出现这样的需求的时候,使用Having 子句。
SELECT department_id, AVG(salary) FROM employees
GROUP BY department_id
HAVING AVG(salary) > 8000;
  • 分组计算函数也可嵌套使用。
SELECT MAX(AVG(salary))
FROM employees
GROUP BY department_id;

子查询

  • 注意点 单行比较必须对应单行子查询 多行比较必须对应多行子查询(返回一个数据集合的查询);比如 IN , > ANY, > ALL
  • 单行
select employee_id,last_name
from employees
where salary=(
  select min(dalary)
  from employees
);
  • 多行
select employee_id,last_name
from employees
where salary<ANY
(
  select salary
  from employees
  where job_id = 'IT_PROG'
)
and job_id <> 'IT_PROG';

DML语句

  • DML:数据操纵语言,简单的说就是SQL中的增删改等语句。
  • Insert语句:1.写出表名+列名 2.仅写表名 第二种方式:在value中必须对应写出每个列的值,即是允许null 的字段,也必须显式的给出null值。 3.把查询结果作为插入的数据 4.把子查询作为插入目标
Insert into sales_reps(id, name, salary, commission_pct)
    SELECT employee_id, last_name, salary, commission_pct
    FROM employees
    where job_id like '%rep%';
  • update语句,可以使用子查询的结果作为更新后的值
update employees
set job_id = (
  sales_reps(id, name, salary, commission_pct)
  SELECT employee_id, last_name, salary, commission_pct
  FROM employees
),salary = (SELECT salary
  FROM employees
  WHERE employee_id = 205)
  WHERE employee_id = 114;
  • delete语句:注意使用truncate,这个语句无法回滚。

子查询进阶

  • 非相关子查询当作一张表来用
select a.last_name,a.salary,a.department_id,b.salavg
from employees a,(select department_id,avg(salary) salavg
from employees group by department_id) b
where a.department_id = b.department_id
and a.salary > b.salavg

sql中exists,not exists的用法

  • exists : 强调的是是否返回结果集,不要求知道返回什么, 比如: select name from student where sex = 'm' and mark exists(select 1 from grade where ...) ,只要 exists引导的子句有结果集返回,那么exists这个条件就算成立了,大家注意返回的字段始终为1,如果改成“select 2 from grade where ...”,那么返回的字段就是2,这个数字没有意义。所以exists子句不在乎返回什么, 而是在乎是不是有结果集返回。

  • 而 exists 与 in 最大的区别在于 in引导的子句只能返回一个字段,比如: select name from student where sex = 'm' and mark in (select 1,2,3 from grade where ...)
    ,in子句返回了三个字段,这是不正确的,exists子句是允许的,但in只允许有一个字段返回, 在1,2,3中随便去了两个字段即可。

  • Show the employee number, last name, salary, department number, and the average salary in their department for all employees.

select e.employee_id,e.last_name,e.department_id,d.avg from employee e,(select department_id,avg(salary) avg from employees group 
by department_id) id
where e.department_id = d.department_id;

SQL进阶

  • 分析函数提供一系列比较高级的sql功能。分析函数时建立在数据窗口(over在一定的数据范围进行数据分析),在一定的数据范围进行排序,汇总等。

  • 如查看当前员工所在部门的平均工资,最高工资和最低工资,即可通过分析函数来实现

SELECT e.last_name,
e.salary,
d.department_name,
AVG(e.salary) over(PARTITION BY d.department_name) department_avg_salary,
MAX(e.salary) over(PARTITION BY d.department_name) department_max_salary,
MIN(e.salary) over(PARTITION BY d.department_name) department_min_salary
FROM employees e, departments d
WHERE 1 = 1
AND e.department_id = d.department_id;
  • 将一个部门内的员工的工资从高到低排序,
select d.department_name,e.last_name,e.salary,
rank() over(partition by department_name order by e.salary desc) dept_salary_rank1,
dense_rank() over(PARTITION BY d.department_name ORDER BY e.salary DESC) dept_salary_rank2,
row_number() over(PARTITION BY d.department_name ORDER BY e.salary DESC) dept_salary_rank3
FROM employees e, departments d
WHERE 1 = 1
AND e.department_id = d.department_id;
  • 综合案列:显示部门编号、名称、员工人数和平均工资 部门,以及在每个部门工作的员工的姓名、薪水和工作 部门
SELECT CASE
         WHEN RANK()
          OVER(PARTITION BY DEP.DEPARTMENT_ID ORDER BY EMP.SALARY ASC) = 1 THEN
          DEP.DEPARTMENT_ID
         ELSE
          NULL
       END "DEPARTMENT_ID",
       CASE
         WHEN RANK()
          OVER(PARTITION BY DEP.DEPARTMENT_ID ORDER BY EMP.SALARY ASC) = 1 THEN
          DEP.DEPARTMENT_NAME
         ELSE
          NULL
       END "DEPARTMENT_NAME",
       CASE
         WHEN RANK()
          OVER(PARTITION BY DEP.DEPARTMENT_ID ORDER BY EMP.SALARY ASC) = 1 THEN
          COUNT(EMP.EMPLOYEE_ID) OVER(PARTITION BY DEP.DEPARTMENT_ID)
         ELSE
          NULL
       END "EMPLOYEES",
       CASE
         WHEN EMP.SALARY IS NULL THEN
          'No average'
         WHEN RANK()
          OVER(PARTITION BY DEP.DEPARTMENT_ID ORDER BY EMP.SALARY ASC) = 1 THEN
          TO_CHAR(AVG(EMP.SALARY) OVER(PARTITION BY DEP.DEPARTMENT_ID),
                  '999999.99')
         ELSE
          NULL
       END "AVG_SAL",
       EMP.LAST_NAME,
       EMP.SALARY,
       EMP.JOB_ID
  FROM EMPLOYEES EMP, DEPARTMENTS DEP
 WHERE EMP.DEPARTMENT_ID(+) = DEP.DEPARTMENT_ID;

关于exists的优化

  • 看代码
select d.department_id
from departments d
where d.department_id !=(
select distinct department_id from employees
where job_id = 'SA_REP' and department_id is not null
)
select d.department_id
from departments d
where d.department_id not in(
select  department_id from employees
where job_id = 'SA_REP' and department_id is not null
)
select d.department_id
from departments d
where  not exists(
select  department_id from employees
where job_id = 'SA_REP' and department_id is not null
)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值