查询每个部门工资前两名的通用sql解析

emp表结构:

[quote]
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------

EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
[/quote]
[quote]
DEPTNO ENAME SAL
---------- ---------- ----------
20 SMITH 860
30 ALLEN 1750
30 WARD 1400
20 JONES 3035
30 MARTIN 1400
30 BLAKE 3000
10 CLARK 2480
20 SCOTT 3060
10 KING 5030
30 TURNER 1650
20 ADAMS 1160
30 JAMES 1100
20 FORD 3060
10 MILLER 1330
[/quote]
Oracle查询:(利用分区功能)

select * from
(select deptno,ename,sal,row_number() over (partition by deptno
order by sal desc) rn
from emp)
where rn<3;

MS SQL:(top)

SELECT TOP 2(SELECT COUNT(*) FROM EMP
WHERE SAL>=A.SAL) AS mc,A.sal FROM EMP AS A
GROUP BY DEPTNO ORDER BY deptno SAL desc;

通用sql:

select deptno, ename, sal
from emp e1
where
(select count(1)
from emp e2
where e2.deptno=e1.deptno and e2.ename!=e1.ename and e2.sal>e1.sal)
<2
order by deptno, sal desc;

现在开始分析这个通用的:
1、

select deptno, ename, sal from emp e1
order by deptno, sal desc;

先不考虑查询条件,表 e1 按照deptno 正序、sal倒序排列
[quote]
E1
DEPTNO ENAME SAL
10 KING 5030
10 CLARK 2480
10 MILLER 1330
20 SCOTT 3060
20 FORD 3060
20 JONES 3035
20 ADAMS 1160
20 SMITH 860
30 BLAKE 3000
30 ALLEN 1750
30 TURNER 1650
30 MARTIN 1400
30 WARD 1400
30 JAMES 1100
[/quote]
2、要查询 e1表中的数据,且要参考e2中数据。e1是主表,e2是附表。
下面来看

where e2.deptno=e1.deptno and e2.ename!=e1.ename and e2.sal>e1.sal

这个条件,其中e2.ename!=e1.ename在这个表中基本可以忽略,因为emp表中没有
deptno、ename、sal都相同的记录,这里它只是起到个确保准确性的作用,不是这个问
题的关键条件。

e2.deptno=e1.deptno and e2.sal>e1.sal

抽取emp中deptno=10的记录,根据这个条件,你会发现:
[quote]
E2 E1
DEPTNO=10 ENAME SAL DEPTNO=10 ENAME SAL
10 KING 5030
10 KING 5030 10 CLARK 2480
10 KING 5030 10 MILLER 1330
10 CLARK 2480 10 MILLER 1330
10 MILLER 1330
[/quote]

where (select count(1) from emp e2 where
e2.deptno=e1.deptno and e2.ename!=e1.ename and e2.sal>e1.sal)
<2

count(1)求的是满足条件的记录数。
当 count(1)=0 时,
[quote]
E2 E1
DEPTNO=10 ENAME SAL DEPTNO=10 ENAME SAL
10 KING 5030
[/quote]
表 e2 中没有记录,表 e1中是该部门工资最高的。

当 count(1)=1 时,
[quote]
E1 E2
DEPTNO=10 ENAME SAL DEPTNO=10 ENAME SAL
[color=white] 10 KING 5030[/color]
10 KING 5030 10 CLARK 2480
[/quote]
表 e2 中是该部门工资最高的,表 e1中是该部门工资次高的。

当 count(1)=2 时,
[quote]
E2 E1
DEPTNO=10 ENAME SAL DEPTNO=10 ENAME SAL
[color=white] 10 KING 5030
10 KING 5030 10 CLARK 2480[/color]
10 KING 5030 10 MILLER 1330
[/quote]
表 e2 中是该部门工资最高的,表 e1中是该部门工资第三高的。

至于为什么会分组求 count(1),是因为相关子查询实现了分组。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值