提问人:David H 提问时间:3/11/2022 最后编辑:David H 更新时间:3/11/2022 访问量:73
MySQL - 将表连接到自身/子查询
MySQL - joining a table to itself / sub queries
问:
我正在就我最近弄错的评估问题寻求帮助,我已经尝试了许多解决方案,并认为我有点知道我想做什么,但似乎无法弄清楚语法。
我有一个表格,如下所示,但有更多记录。
MyTable
ID Name DivisionID ManagerID Salary
123 John Smith 100 789 40000
456 Harold Johnson 101 null 60000
789 Vicky Brown 100 null 80000
并且必须选择薪水第三高的人的那一行,我没有问题。但是,我还需要返回 Manager Name,而不是 ManagerID,这需要从同一表中查找。
我尝试了以下解决方案,这似乎有点不优雅,并且必须在其中硬编码相同的查询,因此不适合扩展或一般用途:
SELECT
table.ID,
Name,
DivisionID,
(SELECT
Name FROM table WHERE id=(
SELECT ManagerID FROM table ORDER BY Salary DESC LIMIT 2,1)
) AS ManagerName,
Salary
FROM table
ORDER BY Salary DESC LIMIT 2,1;
我认为可能有一些方法可以对子查询做到这一点,例如首先在仅经理 ID 和名称的查询中选择一个单独的表,然后从中进行选择 - 但我似乎无法正确理解语法或了解它。我认为表别名也可能是可能的,我从同一表中以不同的别名选择两个不同的结果,然后将两者连接起来,但再次无法弄清楚如何做到这一点。以下是我尝试对别名执行的操作
SELECT
a.ID,
a.Name,
a.DivisionID,
b.Name AS ManagerName
a.Salary
FROM table a
INNER JOIN table b ON a.ManagerID=b.ID
ORDER BY Salary DESC LIMIT 2,1;
答:
首先,当被要求返回第 n 个最大/最小值时,您必须问在出现平局时该怎么办。他们想要薪水第三高的人,所以薪水是 1000、1000、900、900、800、800、700、600、500,我想你想归还收入 800 的人,因为这是第三高的薪水。如果你只是按工资排序,跳过两个,拿第三个,那么你随意挑选一个工资为900的人,900甚至不是第三高的,而是第二高的工资。
为了获得经理,只需再次加入表格即可。对于薪水第三高的员工本身就是经理的情况,您应该使用外部联接。
直接的解决方案是用以下命令对行进行排名:DENSE_RANK
select *
from
(
select t.*, dense_rank() over (order by salary desc) as rnk
from mytable t
) employee
left join mytable manager on manager.id = employee.managerid
where employee.rnk = 3;
MySQL从版本8开始支持。在旧版本中,您必须再次查找同一表。选择不同的工资,并在这些销售中使用您的限制/抵消条款。DENSE_RANK
select *
from mytable employee
left join mytable manager on manager.id = employee.managerid
where employee.salary =
(
select distinct salary
from mytable
order by salary desc
limit 2, 1
);
演示:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=6b17e369fcd4f99ddc6c268de15f08a1
评论
Maka a subquersy form you code for the thrd and join selj join the table
这也适用于 MySQL 5.7 及更早版本
CREATE TABLE MyTable ( `ID` INTEGER, `Name` VARCHAR(14), `DivisionID` INTEGER, `ManagerID` VARCHAR(4), `Salary` INTEGER ); INSERT INTO MyTable (`ID`, `Name`, `DivisionID`, `ManagerID`, `Salary`) VALUES ('123', 'John Smith', '100', '789', '40000'), ('456', 'Harold Johnson', '101', 'null', '60000'), ('789', 'Vicky Brown', '100', 'null', '80000');
SELECT m1.ID, m1.Name, m1. DivisionID,m2. Name, m1.Salary FROM (SELECT `ID`, `Name`, `DivisionID`, `ManagerID`, `Salary` FROM MyTable ORDER BY Salary DESC LIMIT 2,1) m1 JOIN MyTable m2 on m1.ManagerID = m2.ID
ID | Name | DivisionID | Name | Salary --: | :--------- | ---------: | :---------- | -----: 123 | John Smith | 100 | Vicky Brown | 40000
db<>fiddle 在这里
评论