这两个表是salary_employee和employee
employee_salary
salary_id emp_id salary
员工
emp_id | first_name | last_name | gender | email | mobile | dept_id | is_active
查询以获得n个最高工资的所有员工,其中n = 1,2,3,...任意整数
SELECT a.salary, b.first_name
FROM employee_salary a
JOIN employee b
ON a.emp_id = b.emp_id
WHERE a.salary = (
SELECT salary
FROM employee_salary
GROUP BY salary
DESC
LIMIT 1 OFFSET N-1
)
我的问题:
1)有没有更好的和优化的方式我们可以查询,
2)使用LIMIT是一个不错的选择
3)我们有更多的选择来计算第n个最高薪水,这是最好的,什么可以跟随,什么时候?
使用的一个选项:
SELECT *
FROM employee_salary t1
WHERE ( N ) = ( SELECT COUNT( t2.salary )
FROM employee_salary t2
WHERE t2.salary >= t1.salary
)
使用排名方法
SELECT salary
FROM
(
SELECT @rn := @rn + 1 rn,
a.salary
FROM tableName a, (SELECT @rn := 0) b
GROUP BY salary DESC
) sub
WHERE sub.rn = N
答案 0 :(得分:3)
评论太长了。
您已经问过似乎是一个合理的问题。在SQL中有不同的处理方式,有时候某些方法比其他方法更好。排名问题只是许多例子中的一个。 "答案"你的问题是,一般来说,order by
在MySQL中的表现要优于group by
。虽然这取决于特定的数据以及您认为的更好的"。
问题的具体问题是你有三个不同的查询返回三个不同的东西。
第一个返回所有员工的密集等级"那是一样的。该术语是故意使用的,因为它对应于MySQL不支持的ANSI dense_rank()
函数。因此,如果您的工资是100,100和10,它将返回两行,排名为1,一行排名为2.
如果存在关系,则第二个返回不同的结果。如果工资是100,100,10,则此版本将不返回排名为1的行,排名为2的两行,以及排名为3的一行。
第三个返回一个完全不同的结果集,这只是工资的薪水和排名。
我的评论旨在尝试对您的数据进行查询。事实上,你应该从功能和性能的角度来决定你真正想要的东西。
答案 1 :(得分:1)
LIMIT要求SQL浏览0到N之间的所有记录,因此需要增加您想要查看的排名的后续时间。但是,IMO认为这个问题无法更好地解决。
正如Gordon Linoff所建议的那样:使用常用的排名运行您的选项(通常使用哪些排名,哪些排名不是?结果可能在排名1上快,但在排名100上可怕)。
执行并分析Query Execution Plan并相应地创建索引(例如在薪水栏上)并重新测试您的查询。
其他选择:
选项4:
您可以构建一个用作缓存的排名表。您的Limit-Query的执行计划显示(see sqlfiddle here),mysql已经创建了一个临时表来解决查询。
优点:简单快捷 缺点:强制您在每次数据更改时重新生成排名表
选项5:
您可以重新考虑如何定义" rank"。 如果我们有以下工资:
员工Nr 3是否被认为是3级或2级? 1和2是同一等级(等级1),但3是等级3?
如果您定义rank = order,则可以大大简化查询
SELECT a.salary,b.first_name FROM employee_salary a,员工b WHERE a.emp_id = b.emp_id 按薪水排序 限制1 OFFSET 4
答案 2 :(得分:0)
试试这个,
SELECT * FROM one as A WHERE ( n ) = ( SELECT COUNT(DISTINCT(b.salary)) FROM one as B WHERE
B.salary >= A.salary )
答案 3 :(得分:0)
假设emp_salary表具有以下记录:
并且您希望选择所有员工,其中nth(N = 1,2,3等)最高/最低(仅更改>(最高),<(最低)运营商根据您的需要)薪水,使用下面的sql:
SELECT DISTINCT(a.salary),
a.id,
a.name
FROM emp_salary a
WHERE N = (SELECT COUNT( DISTINCT(b.salary)) FROM emp_salary b
WHERE b.salary >= a.salary
);
例如,如果要选择薪水第二高的所有员工,请使用以下sql:
SELECT DISTINCT(a.salary),
a.id,
a.name
FROM emp_salary a
WHERE 2 = (SELECT COUNT( DISTINCT(b.salary)) FROM emp_salary b
WHERE b.salary >= a.salary
);
但是如果你想只显示第二高的薪水(只有一个记录),请使用下面的sql:
SELECT DISTINCT(a.salary),
a.id,
a.name
FROM emp_salary a
WHERE 2 = (SELECT COUNT( DISTINCT(b.salary)) FROM emp_salary b
WHERE b.salary >= a.salary
) limit 1;