จะหาเงินเดือนสูงสุดที่สามหรือnᵗʰจากตารางเงินเดือนได้อย่างไร?


100

วิธีการหาหรือ n สามTHเงินเดือนสูงสุดจากเงินเดือนtable(EmpID, EmpName, EmpSalary)ในทางที่ดีที่สุด?



1
SELECT salary FROM (SELECT salary FROM employee ORDER BY salary DESC FETCH NEXT 3 ROWS ONLY) ORDER BY salary ASC FETCH NEXT 1 ROWS ONLY;
Sathvik

คำตอบ:


85

ใช้ROW_NUMBER(ถ้าคุณต้องการเดี่ยว) หรือDENSE_RANK(สำหรับแถวที่เกี่ยวข้องทั้งหมด):

WITH CTE AS
(
    SELECT EmpID, EmpName, EmpSalary,
           RN = ROW_NUMBER() OVER (ORDER BY EmpSalary DESC)
    FROM dbo.Salary
)
SELECT EmpID, EmpName, EmpSalary
FROM CTE
WHERE RN = @NthRow

วิธีรับบันทึกเงินเดือนขั้นต่ำจากตาราง? เลือก ins.KYS_ID, ins.FKYS_INS_ID จาก cmn_pat_x_insurance ins โดยที่ ins FKYS_PAT_ID = '1253_717' และ ins.FKYS_INS_TYPE ใน (1) และ ins.BOL_TYPE ใน (1,3) และ ins.salary ใน (min (ins.salary))
saidesh kilaru

ลองนึกภาพว่ามี 10,0000 ระเบียนในตารางพนักงาน หากฉันใช้คำค้นหาข้างต้นประสิทธิภาพจะลดลง 6-10 ครั้ง
Bimal Das

1
@BimalDas: คุณไม่มีดัชนีในEmpSalaryคอลัมน์ ยังลดลงเมื่อเทียบกับอะไร? ข้อได้เปรียบของวิธีการคือการที่คุณสามารถใช้ROW_NUMBER ..OVER(PARTITION BY GroupColumn OrderBy OrderColumn)ดังนั้นคุณสามารถใช้เพื่อรับกลุ่ม แต่ยังเข้าถึงคอลัมน์ใดก็ได้
Tim Schmelter

@TimSchmelter ด้วย CTE จะสร้างตารางชั่วคราวเพื่อเก็บข้อมูลทั้งหมดของคำสั่ง SELECT แรกไว้ในนั้นจากนั้นเราเลือก "SELECT EmpID, EmpName, EmpSalary จาก CTE WHERE RN = @NthRow" นั่นคือเหตุผลที่ฉันเดาว่ามันช้าไปหน่อย ฉันตรวจสอบแล้ว และฉันยังมีการจัดทำดัชนีที่เหมาะสม
Bimal Das

2
@BimalDas: ไม่มันไม่ได้สร้างตารางชั่วคราว โดยปกติ cte จะไม่ปรากฏขึ้นที่ใดก็ได้ มันเหมือนกับมุมมองแบบอินไลน์หรือคิวรีย่อยที่ตั้งชื่อ
Tim Schmelter

90

หมายเลขแถว:

SELECT Salary,EmpName
FROM
  (
   SELECT Salary,EmpName,ROW_NUMBER() OVER(ORDER BY Salary) As RowNum
   FROM EMPLOYEE
   ) As A
WHERE A.RowNum IN (2,3)

แบบสอบถามย่อย:

SELECT *
FROM Employee Emp1
WHERE (N-1) = (
               SELECT COUNT(DISTINCT(Emp2.Salary))
               FROM Employee Emp2
               WHERE Emp2.Salary > Emp1.Salary
               )

คำหลักยอดนิยม:

SELECT TOP 1 salary
FROM (
      SELECT DISTINCT TOP n salary
      FROM employee
      ORDER BY salary DESC
      ) a
ORDER BY salary

วิธีรับบันทึกเงินเดือนขั้นต่ำจากตาราง? เลือก ins.KYS_ID, ins.FKYS_INS_ID จาก cmn_pat_x_insurance ins โดยที่ ins FKYS_PAT_ID = '1253_717' และ ins.FKYS_INS_TYPE ใน (1) และ ins.BOL_TYPE ใน (1,3) และ ins.salary ใน (min (ins.salary))
saidesh kilaru

คูมาร์และอเล็กซานเดอร์ฉันต้องการเพิ่มอีกหนึ่งฟิลด์ด้วยจะทำอย่างไร ข้อความค้นหาของฉันเหมือน "" "เลือก Top 1 NoteID จาก (เลือก DateDiff (Year, SchedualDate, Current_TimeStamp) เป็น NoteAge, NoteID 3 อันดับแรกที่แตกต่างจาก [dbo] [DocSecheduale] เรียงลำดับตาม NoteID Desc) a Order by NoteID" ""
Zaveed Abbasi

ฉันพบว่าเงินเดือนสูงสุดอันดับที่ n แต่ฉันได้รับความซับซ้อนในการทำความเข้าใจแบบสอบถามย่อยคุณต้องการอธิบายคำถามย่อยหรือไม่ ...
Deepak Gupta

@deepak_java แบบสอบถามย่อยจะได้รับการประเมินแต่ละครั้งและทุกครั้งที่มีการประมวลผลแถวของคิวรีภายนอก กล่าวอีกนัยหนึ่งคือไม่สามารถประมวลผลแบบสอบถามภายในโดยไม่ขึ้นกับแบบสอบถามภายนอกเนื่องจากแบบสอบถามภายในใช้ค่า Emp1 เช่นกัน
Kumar Manish

สิ่งสำคัญคือต้องเข้าใจว่าเหตุใดจึงต้อง... WHERE (N-1) = (Subquery)...ทำงาน แบบสอบถามย่อยเป็นแบบสอบถามที่สัมพันธ์กันเนื่องจากWHEREส่วนคำสั่งใช้Emp1จากแบบสอบถามหลัก แบบสอบถามย่อยจะได้รับการประเมินทุกครั้งที่ข้อความค้นหาหลักสแกนในแถว ตัวอย่างเช่นถ้าเราจะหาเงินเดือนที่ใหญ่เป็นอันดับ 3 (N = 3) จาก (800, 1000, 700, 750) แบบสอบถามย่อยสำหรับแถวที่ 1 จะSELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800เป็น 0 สำหรับค่าเงินเดือนที่ 4 (750) ... WHERE Emp2.Salary > 750จะเป็น 2 หรือ N -1 ดังนั้นแถวนี้จะถูกส่งกลับ
jerrymouse

66

ลองทำตามนี้

SELECT TOP 1 salary FROM (
   SELECT TOP 3 salary 
   FROM employees 
   ORDER BY salary DESC) AS emp 
ORDER BY salary ASC

สำหรับ 3 คุณสามารถแทนที่ค่าใดก็ได้ ...


มันใช้ได้กับ oracle 10g หรือ 11g? หรือมีทางเลือกอื่นที่สวยแบบนี้?
RBz

43

หากคุณต้องการวิธีเพิ่มประสิทธิภาพให้ใช้TOPKeyword ดังนั้นแบบสอบถามเงินเดือนสูงสุดและขั้นต่ำที่ n มีดังนี้ แต่แบบสอบถามดูเหมือนจะยุ่งยากเหมือนในลำดับย้อนกลับโดยใช้ชื่อฟังก์ชันรวม:

N เงินเดือนสูงสุด:

SELECT MIN(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP N EmpSalary FROM Salary ORDER BY EmpSalary DESC) 

สำหรับเงินเดือนสูงสุด 3 เท่า:

SELECT MIN(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP 3 EmpSalary FROM Salary ORDER BY EmpSalary DESC) 

N เงินเดือนขั้นต่ำ:

SELECT MAX(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP N EmpSalary FROM Salary ORDER BY EmpSalary ASC)

สำหรับเงินเดือนขั้นต่ำ 3:

SELECT MAX(EmpSalary)
FROM Salary
WHERE EmpSalary IN(SELECT TOP 3 EmpSalary FROM Salary ORDER BY EmpSalary ASC)

ง่ายที่สุดและจำง่ายที่สุด +1
Sнаđошƒаӽ

4
เพื่อให้ได้เงินเดือนสูงสุดว่าทำไมเราถึงทำตามลำดับ ASC ต้องทำตามคำสั่ง DESC ถ้าเรามีเงินเดือนเช่นนี้ 7000,10000,11000,500,800,900,12000 การค้นหาภายในของการเรียงลำดับจะส่งผลให้ top3 ซึ่งหมายความว่า 500,800,900 และสูงสุดคือ 900 แต่ 900 ไม่ใช่ 3 สูงสุด 3 เงินเดือนสูงสุดคือ 10,000
Narendra Jaggi

1
สำหรับเช่น: เงินเดือนสูงสุด 3: ต้องเป็นเช่นนั้น SELECT Min (EmpSalary) จากเงินเดือน WHERE EmpSalary IN (SELECT TOP 3 EmpSalary จากการสั่งเงินเดือนโดย EmpSalary DESC)
Jimit Rupani

15

ง่ายเกินไปถ้าคุณใช้แบบสอบถามย่อย!

SELECT MIN(EmpSalary) from (
SELECT EmpSalary from Employee ORDER BY EmpSalary DESC LIMIT 3
);

คุณสามารถเปลี่ยนค่าที่ n หลังข้อ จำกัด LIMIT ได้ที่นี่

ในนี้แบบสอบถามย่อยเลือก EmpSalary จากคำสั่งของพนักงานโดย EmpSalary DESC Limit 3; จะคืนเงินเดือน 3 อันดับแรกของพนักงาน จากผลลัพธ์เราจะเลือกเงินเดือนขั้นต่ำโดยใช้คำสั่ง MIN เพื่อรับเงินเดือน TOP อันดับ 3 ของพนักงาน


รับข้อผิดพลาดนี้ รหัสข้อผิดพลาด: 1248 ทุกตารางที่ได้รับต้องมีนามแฝงของตัวเอง

เพิ่มนามแฝงให้ .. SELECT MIN (EmpSalary) จาก (SELECT EmpSalary from Employee ORDER BY EmpSalary DESC LIMIT 3) as;
anonxss

เพียงใช้ DISTINCT เพื่อหลีกเลี่ยงรายการที่ซ้ำกัน SELECT MIN (EmpSalary) จาก (SELECT DISTINCT (EmpSalary) จาก Employee ORDER BY EmpSalary DESC LIMIT 3);
Kalpesh Parikh

14

แทนที่ N ด้วย Max Number ของคุณ

SELECT *
FROM Employee Emp1
WHERE (N-1) = (
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp2.Salary > Emp1.Salary)

คำอธิบาย

แบบสอบถามด้านบนอาจทำให้สับสนได้หากคุณไม่เคยเห็นสิ่งใดมาก่อน - แบบสอบถามภายในคือสิ่งที่เรียกว่าแบบสอบถามย่อยที่สัมพันธ์กันเนื่องจากแบบสอบถามภายใน (แบบสอบถามย่อย) ใช้ค่าจากแบบสอบถามภายนอก (ในกรณีนี้คือตาราง Emp1 ) อยู่ในคำสั่ง WHERE

และSource


+1 สิ่งสำคัญคือต้องเข้าใจว่าเหตุใดจึงได้... WHERE (N-1) = (Subquery)...ผล แบบสอบถามย่อยเป็นแบบสอบถามที่สัมพันธ์กันเนื่องจากWHEREส่วนคำสั่งใช้Emp1จากแบบสอบถามหลัก แบบสอบถามย่อยจะได้รับการประเมินทุกครั้งที่ข้อความค้นหาหลักสแกนในแถว ตัวอย่างเช่นถ้าเราจะหาเงินเดือนที่ใหญ่เป็นอันดับ 3 (N = 3) จาก (800, 1000, 700, 750) แบบสอบถามย่อยสำหรับแถวที่ 1 จะSELECT COUNT(DISTINCT(Emp2.Salary)) FROM Employee Emp2 WHERE Emp2.Salary > 800เป็น 0 สำหรับค่าเงินเดือนที่ 4 (750) ... WHERE Emp2.Salary > 750จะเป็น 2 หรือ N -1 ดังนั้นแถวนี้จะถูกส่งกลับ
jerrymouse

13

เงินเดือนสูงสุดที่สามหรือที่ n จากตารางเงินเดือนโดยไม่ต้องใช้แบบสอบถามย่อย

select salary from salary
   ORDER   BY salary DESC
   OFFSET  N-1 ROWS
   FETCH NEXT 1 ROWS ONLY

สำหรับเงินเดือนสูงสุดอันดับ 3 ให้วาง 2 แทน N-1


3
สิ่งสำคัญที่ต้องพูดถึงว่า OFFSET FETCH พร้อมใช้งานจากเวอร์ชัน SQL Server 2012 +
Zerotoinfinity



8

อ้างถึงคำถามต่อไปนี้เพื่อรับเงินเดือนสูงสุดอันดับที่ n ด้วยวิธีนี้คุณจะได้รับเงินเดือนสูงสุดอันดับที่ n ใน MYSQL หากคุณต้องการได้รับเงินเดือนต่ำสุดอันดับที่ n คุณต้องแทนที่ DESC ด้วย ASC ในแบบสอบถาม เงินเดือนสูงสุดอันดับที่ n


1
คำถามเกี่ยวกับ SQL-Server ไม่ใช่ MySQL
bummi

6

วิธีที่ 1:

SELECT TOP 1 salary FROM (
SELECT TOP 3 salary 
 FROM employees 
  ORDER BY salary DESC) AS emp 
 ORDER BY salary ASC

วิธีที่ 2:

  Select EmpName,salary from
  (
    select EmpName,salary ,Row_Number() over(order by salary desc) as rowid      
     from EmpTbl)
   as a where rowid=3

วิธีที่ 1 สามารถจัดเรียงได้: เลือกเงินเดือนสูงสุด 1 อันดับแรกจากพนักงาน (SELECT TOP 3 SALARY FROM EMPLOYEES) * เหตุผล - เพราะโดยค่าเริ่มต้นเรียงลำดับจากน้อยไปหามาก
Ashish Agrawal Yodlee

5

ในปี 2008 เราสามารถใช้ ROW_NUMBER () OVER (ORDER BY EmpSalary DESC) เพื่อรับอันดับที่ไม่มีความสัมพันธ์ที่เราสามารถใช้ได้

ตัวอย่างเช่นเราสามารถทำได้สูงสุดเป็นอันดับ 8 ด้วยวิธีนี้หรือเปลี่ยน @N เป็นอย่างอื่นหรือใช้เป็นพารามิเตอร์ในฟังก์ชันก็ได้หากต้องการ

DECLARE @N INT = 8;
WITH rankedSalaries AS
(
SELECT
EmpID
,EmpName
,EmpSalary,
,RN = ROW_NUMBER() OVER (ORDER BY EmpSalary DESC)
FROM salary
)
SELECT
EmpID
,EmpName
,EmpSalary
FROM rankedSalaries
WHERE RN = @N;

ใน SQL Server 2012 ดังที่คุณทราบว่าดำเนินการโดยสัญชาตญาณมากขึ้นโดยใช้ LAG ()



4

เพื่อให้ได้ค่าสูงสุดอันดับสามจากตาราง

SELECT * FROM tableName ORDER BY columnName DESC LIMIT 2, 1

เลือกคอลัมน์ที่แตกต่างกันชื่อจากตารางชื่อเรียงลำดับตามคอลัมน์ชื่อ DESC LIMIT 2, 1
Devendra Singraul

3

นี่เป็นหนึ่งในคำถามยอดนิยมในการสัมภาษณ์ SQL ฉันจะเขียนแบบสอบถามต่างๆเพื่อหาค่าสูงสุดอันดับที่ n ของคอลัมน์

ฉันได้สร้างตารางชื่อ“ Emloyee” โดยเรียกใช้สคริปต์ด้านล่าง

CREATE TABLE Employee([Eid] [float] NULL,[Ename] [nvarchar](255) NULL,[Basic_Sal] [float] NULL)

ตอนนี้ฉันจะแทรก 8 แถวในตารางนี้โดยเรียกใช้คำสั่งแทรกด้านล่าง

insert into Employee values(1,'Neeraj',45000)
insert into Employee values(2,'Ankit',5000)
insert into Employee values(3,'Akshay',6000)
insert into Employee values(4,'Ramesh',7600)
insert into Employee values(5,'Vikas',4000)
insert into Employee values(7,'Neha',8500)
insert into Employee values(8,'Shivika',4500)
insert into Employee values(9,'Tarun',9500)

ตอนนี้เราจะพบ Basic_sal สูงสุดอันดับ 3 จากตารางด้านบนโดยใช้แบบสอบถามที่แตกต่างกัน ฉันเรียกใช้แบบสอบถามด้านล่างในสตูดิโอการจัดการและด้านล่างคือผลลัพธ์

select * from Employee order by Basic_Sal desc

เราจะเห็นในภาพด้านบนว่าเงินเดือนขั้นพื้นฐานสูงสุดอันดับ 3 จะเป็น 8500 ฉันกำลังเขียน 3 วิธีที่แตกต่างกันในการทำเช่นเดียวกัน เมื่อเรียกใช้แบบสอบถามทั้งสามที่กล่าวถึงด้านล่างเราจะได้ผลลัพธ์เดียวกันคือ 8500

วิธีแรก: - ใช้ฟังก์ชันหมายเลขแถว

select Ename,Basic_sal
from(
            select Ename,Basic_Sal,ROW_NUMBER() over (order by Basic_Sal desc) as rowid from Employee
      )A
where rowid=2

3
Select TOP 1 Salary as '3rd Highest Salary' from (SELECT DISTINCT TOP 3 Salary from Employee ORDER BY Salary DESC) a ORDER BY Salary ASC;

ฉันแสดงเงินเดือนสูงสุดเป็นอันดับ 3



3

- เงินเดือนสูงสุด

select * 
from (select lstName, salary, row_number() over( order by salary desc) as rn 
      from employee) tmp
where rn = 2

- (ที่ n -1) เงินเดือนสูงสุด

select * 
from employee e1
where 1 = (select count(distinct salary)  
           from employee e2
           where e2.Salary > e1.Salary )

3

วิธีที่เพิ่มประสิทธิภาพ: แทนที่จะใช้คำค้นหาย่อยให้ใช้ขีด จำกัด

select distinct salary from employee order by salary desc limit nth, 1;

ดูลิมิตไวยากรณ์ที่นี่http://www.mysqltutorial.org/mysql-limit.aspx


ใช่! เป็นวิธีที่ง่ายและสะอาดมาก
Avnish alok




1

โซลูชันที่ทดสอบ MySQL สมมติว่า N = 4:

select min(CustomerID) from (SELECT distinct CustomerID FROM Customers order by CustomerID desc LIMIT 4) as A;

ตัวอย่างอื่น:

select min(country) from (SELECT distinct country FROM Customers order by country desc limit 3);


1

ค้นหาเงินเดือนสูงสุด Nth จากตาราง นี่คือวิธีการทำงานนี้โดยใช้ฟังก์ชัน density_rank ()

ป้อนคำอธิบายภาพที่นี่

select linkorder from u_links

select max(linkorder) from u_links

select max(linkorder) from u_links where linkorder < (select max(linkorder) from u_links)

select top 1 linkorder 
       from ( select distinct top 2 linkorder from u_links order by linkorder desc) tmp 
order by linkorder asc

DENSE_RANK: 1. DENSE_RANK คำนวณอันดับของแถวในกลุ่มแถวที่เรียงลำดับและส่งกลับอันดับเป็น NUMBER อันดับคือจำนวนเต็มติดต่อกันที่ขึ้นต้นด้วย 1 2. ฟังก์ชันนี้ยอมรับอาร์กิวเมนต์เป็นชนิดข้อมูลตัวเลขและส่งกลับ NUMBER 3. ในฐานะฟังก์ชันการวิเคราะห์ DENSE_RANK จะคำนวณอันดับของแต่ละแถวที่ส่งคืนจากคิวรีเทียบกับแถวอื่น ๆ โดยอิงตามค่าของ value_exprs ใน order_by_clause 4. ในแบบสอบถามด้านบนอันดับจะถูกส่งกลับตาม sal ของตารางพนักงาน ในกรณีที่เสมอกันจะกำหนดอันดับที่เท่ากันให้กับทุกแถว

WITH result AS ( 
     SELECT linkorder ,DENSE_RANK() OVER ( ORDER BY linkorder DESC ) AS  DanseRank 
FROM u_links ) 
SELECT TOP 1 linkorder FROM result WHERE DanseRank = 5

1

ใน SQL Server 2012+ OFFSET ... FETCH จะเป็นวิธีที่มีประสิทธิภาพในการบรรลุสิ่งนี้:

DECLARE @N AS INT;
SET @N = 3;

SELECT
    EmpSalary
FROM
    dbo.Salary
ORDER BY
    EmpSalary DESC
OFFSET (@N-1) ROWS
FETCH NEXT 1 ROWS ONLY

1
select * from employee order by salary desc;

+------+------+------+-----------+
| id   | name | age  | salary    |
+------+------+------+-----------+
|    5 | AJ   |   20 | 100000.00 |
|    4 | Ajay |   25 |  80000.00 |
|    2 | ASM  |   28 |  50000.00 |
|    3 | AM   |   22 |  50000.00 |
|    1 | AJ   |   24 |  30000.00 |
|    6 | Riu  |   20 |  20000.00 |
+------+------+------+-----------+




select distinct salary from employee e1 where (n) = (select count( distinct(salary) ) from employee e2 where e1.salary<=e2.salary);

แทนที่ n ด้วยเงินเดือนสูงสุดอันดับที่ n เป็นตัวเลข


0
SELECT TOP 1 salary FROM ( SELECT TOP n salary FROM employees ORDER BY salary DESC Group By salary ) AS emp ORDER BY salary ASC

(โดยที่ n สำหรับเงินเดือนสูงสุดที่ n)


0

เพียงแค่เปลี่ยนค่าแบบสอบถามภายในเช่นเลือกด้านบน (2) * จากลำดับ Student_Info ตาม ClassID desc

ใช้สำหรับปัญหาทั้งสอง:

Select Top (1)* from 
(
 Select Top (1)* from Student_Info order by ClassID desc 
) as wsdwe
order by ClassID 

0

การสอบถามnth highest bonusการพูดn=10โดยใช้ AdventureWorks2012 ลองรหัสต่อไปนี้

USE AdventureWorks2012; 
GO

SELECT * FROM Sales.SalesPerson;
GO

DECLARE @grade INT;
SET @grade = 10;
SELECT MIN(Bonus)
FROM (SELECT TOP (@grade) Bonus FROM (SELECT DISTINCT(Bonus) FROM Sales.SalesPerson) AS a ORDER BY Bonus DESC) AS g
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.