2012-05-23 72 views
3

查找薪水最高的前2名員工。查找沒有使用頂級薪資最高的前2名員工

表名是salary,列name,salary

我們可以通過限制命令

select * from salary order by salary DESC limit 0,2 

但如何做到這一點,而不使用頂部和限制此查詢?

+1

爲什麼限制?這是功課嗎? – Bernard

+0

這是一個採訪問題,我們不能使用top和limit。 – Luv

+0

是否MySql正確? –

回答

4

我相信這個面試問題試圖指導你嵌套選擇或公用表表達式,或類似的東西。 TOP 2是簡單的答案,顯然TOP只是爲此目的而實施的 - 面試希望你能夠「手動」完成。

理論代碼。在第一個(嵌套的)select上爲每行分配一行數,然後從行數小於1的結果中選擇所需的行數3,在這種情況下爲3。

MySQL - Get row number on select

嵌套SELECT(僞代碼):

select row_count, * from salary order by salary desc 

外選擇:

select * from <nested select> where row_count < 3 

對不起,這不是MySQL的代碼,但只有我知道SQL Server。

我使用該行的作品一些SQL Server代碼數:

declare @Salaries table 
(
    id int, 
    salary money 
) 

insert into @salaries (id, salary) 
values (1, 1), 
(2, 2), 
(3, 3), 
(4, 4), 
(5, 4) -- A duplicating salary 

;WITH Props AS 
(
    SELECT *, 
     ROW_NUMBER() OVER (ORDER BY salary desc) AS RowNumber 
    FROM @Salaries 
) 
SELECT * FROM Props WHERE RowNumber < 3 

這將返回ID爲4和5


應對薩欽Kainth的回答行

我相信這個答案是不正確的。試試下面的SQL Server代碼:

declare @Salaries table 
(
    id int, 
    salary money 
) 

insert into @salaries (id, salary) 
values (1, 1), 
(2, 2), 
(3, 3), 
(4, 4), 
(5, 4) 

select * from @salaries where salary in -- "in" introduces the problem 
(
SELECT MAX(E1.Salary) 
FROM @salaries E1, @salaries E2 
WHERE E1.Salary < E2.Salary 

union 

SELECT MAX(Salary) 
FROM @salaries 
) 

這將返回ID爲3,4和5而不是僅僅4和5這是因爲外有條where salary in選擇將行3,4和5行,所有的工資都由嵌套select(返回工資值3和4)返回。

+0

這是唯一的「面試答案」,因爲它不依賴任何魔術關鍵詞。如果我還剩下任何選票,我會+1 +1 – keyser

+0

如果你填充你的MySQL答案以便它能夠工作,而不是鏈接到「在選擇時獲得行號」 – RedFilter

+0

@RedFilter我不會,我不會不做MySQL。 –

0
select * from salary where salary in 
(
SELECT MAX(E1.Salary) 
FROM Salary E1, Salary E2 
WHERE E1.Salary < E2.Salary 

union 

SELECT MAX(Salary) 
FROM Salary 
) 
+0

這一個取得前2名?你能解釋一下嗎?我很好奇。 – keyser

+0

@Keyser第一部分選擇MAX低於薪水的地方,因爲第一個不低於任何薪水,那麼你應該選擇第二個薪水,然後你將它與第一個結合。不知道當前兩名工資的價值相同時會發生什麼:-) –

+0

我明白了,謝謝。是的,我想這需要'<=' – keyser

1

根據SQL:2008標準,您可以將FETCH FIRST 10 ROWS ONLY附加到您的查詢中。雖然,我從來沒有嘗試過。所以你的情況,你將有

SELECT * FROM salary ORDER BY salary DESC FETCH FIRST 2 ROWS ONLY 
1

這是在MySQL:

SET @row := 0; 
SELECT name, salary FROM 
(SELECT name, salary, @row := @row + 1 AS Row FROM salary ORDER BY salary DESC) 
    AS derived1 
WHERE Row < 3 

仍然有警告。如果有重複的工資,結果可能會出現偏差。如果結果集大於兩行,結果將不會包含在結果中,但由於問題針對的是薪水最高的兩名員工,而不是兩名薪水最高的員工,這是我能做的最好的。

也許正確的答案是要問,「我應該怎麼做在重複薪金的情況下?」

這裏的訣竅,如果它絕對必須是一個查詢:

SELECT name, salary FROM 
(SELECT name, salary, @row := @row + 1 AS Row FROM (SELECT @row := 0) AS d1, salary) 
    AS d2 
WHERE Row < 3 
+0

這應該適用於重複的工資,因爲它們將佔據訂單的前兩行,因此行號只負責選擇兩個行。 +1的MySQL示例,我只能鼓起一個SQL Server示例;-) –

0
+------+ 
| Sal | 
+------+ 
| 3500 | 
| 2500 | 
| 2500 | 
| 5500 | 
| 7500 | 
+------+ 

下面的查詢將返回第N個最大元素。

select SAL from EMPLOYEE E1 where 
(N - 1) = (select count(distinct(SAL)) 
      from EMPLOYEE E2 
      where E2.SAL > E1.SAL) 
0

表結構

CREATE TABLE `emp` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(20) DEFAULT NULL, 
    `salary` int(10) DEFAULT NULL 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 

MySQL查詢爲第n項n表示項目

SELECT salary 
FROM emp 
WHERE salary = (SELECT DISTINCT(salary) 
       FROM emp AS e1 
       WHERE (n) = (SELECT COUNT(DISTINCT(salary)) 
          FROM emp AS e2 
          WHERE e1.salary <= e2.salary)) 
0
SELECT e1.EmployeeID, e1.LastName, COUNT(DISTINCT e2.EmployeeID) AS sals_higher 
FROM Employees e1 
INNER JOIN Employees e2 ON e1.EmployeeID < e2.EmployeeID 
GROUP BY e1.EmployeeID 
HAVING sals_higher <= 2 
ORDER BY e1.EmployeeID DESC 
的第n個數

訪問https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_union3 並嘗試給定的一段代碼,它會給出您前2個最大的EmployeeID。

相關問題