搬山行者

无志愁压头,有志能搬山

业余程序员的学习笔记~


Sql经典实例 第三章

目录

查找只存在于一个表中的记录

select deptno  
  from dept
except   
select deptno  
  from emp

从一个表中检索出与另一个表不相关的行

-- 哪些部门没有员工?
select d.* 
  from dept d left join emp e on d.deptno = e.deptno 
  where e.deptno is null

新增连接查询而不影响其他连接查询

-- 查找所有员工的姓名、部门所在地和奖金
select ename, d.loc, eb.received 
  from emp e join dept d on e.deptno = d.deptno 
  left join emp_bonus eb on e.empno = eb.empno 
  order by loc

确定两个表中是否存在相同的记录

-- 不仅要找出不同的记录,还要找出重复的记录

(seleect empno, ename, job, mgr, hiredate, sal, comm, deptno,
    count(*) as cnt from V 
    group by empno, ename, job, mgr, hiredate, sal, comm, deptno 
    except
    select empno, ename, job, mgr, hiredate, sal, comm, deptno,
      count(*) as cnt 
      from emp 
      group by empno, ename, job, mgr, hiredate, sal, comm, deptno
  )
  union all
  (seleect empno, ename, job, mgr, hiredate, sal, comm, deptno,
    count(*) as cnt from emp 
    group by empno, ename, job, mgr, hiredate, sal, comm, deptno 
    except
    select empno, ename, job, mgr, hiredate, sal, comm, deptno,
      count(*) as cnt 
      from V 
      group by empno, ename, job, mgr, hiredate, sal, comm, deptno
  )

识别并消除笛卡尔积

-- 错误
select e.name, d.loc
  from emp e, dept d
where e.deptno = 10

-- 正确
select e.name, d.loc
  from emp e, dept d
where e.deptno = d.deptno and e.deptno = 10

组合使用连接查询和聚合函数

-- 使用distinct计算工资总额
select deptno, 
  sum(distinct sal) as total_sal,
  sum(bonus) as total_bonus,
  from ( 
    select e.empno, e.ename, e.sal, e.deptno,
     e.sal * case when eb.type = 1 then .1
                  when eb.type = 2 then.05
                  else .3 end as bonus
    from emp e, emp_bonus eb 
    where e.empno = eb.empno and e.deptno = 10
  ) x
  group by deptno

组合使用外连接查询和聚合函数

select deptno, 
  sum(distinct sal) as total_sal,
  sum(bonus) as total_bonus,
  from ( 
    select e.empno, e.ename, e.sal, e.deptno,
     e.sal * case when eb.type = 1 then .1
                  when eb.type = 2 then.05
                  else .3 end as bonus
    from emp e left join emp_bonus eb 
    on e.empno = eb.empno and e.deptno = 10
  ) x
  group by deptno

从多个表中返回缺失值

-- 全外连接(full outer join),基于一个共同值,从两个表中返回缺失值
select d.deptno,d.dname, e.ename
  from emp e full outer join dept d
  on e.deptno = d.deptno