SQL巧用表的自连接和运算符代替排序的几个例子

MySQL巧用表的自连接和运算符代替排序的几个例子

例1: SQL18

获取当前薪水第二多的员工的emp_no以及其对应的薪水salary
步骤一:自连接并筛选s1.salary <= s2.salary的行

SELECT * FROM salaries AS s1
JOIN salaries AS s2 ON s1.salary <= s2.salary
10004740572001-11-279999-01-0110001889582002-06-22
10003433112001-12-019999-01-0110001889582002-06-22
10002725272001-08-029999-01-0110001889582002-06-22
10001889582002-06-229999-01-0110001889582002-06-22
10003433112001-12-019999-01-0110002725272001-08-02
10002725272001-08-029999-01-0110002725272001-08-02
10003433112001-12-019999-01-0110003433112001-12-01
10004740572001-11-279999-01-0110004740572001-11-27
10003433112001-12-019999-01-0110004740572001-11-27
10002725272001-08-029999-01-0110004740572001-11-27

步骤二:查找第二多的工资是多少

SELECT s1.salary FROM salaries AS s1
JOIN salaries AS s2 ON s1.salary <= s2.salary
GROUP BY s1.salary
HAVING COUNT(s2.salary) = 2

步骤三:完善外层查询后的最终代码

SELECT employees.emp_no, salaries.salary,
    employees.last_name, employees.first_name
    
FROM employees JOIN salaries ON
employees.emp_no = salaries.emp_no

WHERE salaries.salary = (
    SELECT s1.salary FROM salaries AS s1
    JOIN salaries AS s2 ON s1.salary <= s2.salary
    GROUP BY s1.salary
    HAVING COUNT(s2.salary) = 2
    )

例2:SQL23

对所有员工的薪水按照salary降序进行1-N的排名

-- rank排名:查询表中大于自己薪水的员工的数量(考虑并列:去重)
SELECT 
  s1.emp_no,
  s1.salary,
  (SELECT 
    COUNT(DISTINCT s2.salary) 
  FROM
    salaries s2 
  WHERE s2.to_date = '9999-01-01' 
    AND s2.salary >= s1.salary) AS `rank`  -- 去重:计算并列排名
FROM
  salaries s1 
WHERE s1.to_date = '9999-01-01' 
ORDER BY s1.salary DESC,
  s1.emp_no ;

也可以使用窗口函数

select emp_no, salary,
       dense_rank() over (order by salary desc) as rank
from salaries
where to_date='9999-01-01'
order by rank asc,emp_no asc;

例3:SQL87

最差是第几名(一)

步骤一: 连接,做笛卡尔积,筛选T2表中比T1小的

SELECT T1.*, T2.*
FROM class_grade T1
JOIN class_grade T2 ON T2.grade <= T1.grade
ORDER BY T1.grade, T2.grade

结果为:

T1.gradeT1带来的无用列T2.grade
A2A2
B2A2
B2B2
C2A2
C2B2
C2C2
D1A2
D1B2
D1C2
D1D1

步骤二:T2.grade分组再求和

SELECT T1.grade, SUM(T2.number) AS t_rank
FROM class_grade T1
JOIN class_grade T2 ON T2.grade <= T1.grade
GROUP BY T1.grade
ORDER BY T1.grade
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值