กรณี SQL เมื่อไม่ติดฉลาก null

Oct 04 2020

ฉันกำลังพยายามทำLeet Code Problem :

เขียนแบบสอบถาม SQL เพื่อรับเงินเดือนสูงสุดอันดับสองจากตารางพนักงาน

+----+--------+
| Id | Salary |
+----+--------+
| 1  | 100    |
| 2  | 200    |
| 3  | 300    |
+----+--------+

ตัวอย่างเช่นจากตารางพนักงานด้านบนแบบสอบถามควรส่งคืน 200 เป็นเงินเดือนสูงสุดอันดับสอง หากไม่มีเงินเดือนสูงสุดเป็นอันดับสองแบบสอบถามควรส่งคืนค่าว่าง

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200                 |
+---------------------+

ฉันกำลังพยายามแก้ปัญหานี้:

SELECT 
      CASE WHEN Salary = '' 
         THEN NULL 
         ELSE Salary END SecondHighestSalary 
   FROM 
      Employee 
   ORDER BY 
      SecondHighestSalary 
   LIMIT 1,1;

เมื่อมีเงินเดือนที่สองจะทำงานได้ดีและส่งคืนผลลัพธ์ อย่างไรก็ตามเมื่อไม่มีเงินเดือนที่สองและมีเพียงเงินเดือนเดียวจะส่งคืนสตริงว่างเท่านั้น ฉันพยายามจะกลับNULLแต่มันกลับไม่NULLเหมือนที่ฉันเขียนในแบบสอบถามของฉัน ฉันจะแก้ไขปัญหานี้ได้อย่างไร?

คำตอบ

3 Barmar Oct 04 2020 at 07:11

CASEนิพจน์ของคุณกำลังทดสอบเงินเดือนในแต่ละแถวของตารางไม่ใช่ค่าที่เลือกโดยLIMITอนุประโยค การสั่งซื้อจะเสร็จสิ้นหลังจากสร้างค่าในSELECTรายการเนื่องจากคุณสามารถเรียงลำดับตามค่าที่คำนวณได้

เนื่องจากไม่มีเงินเดือนใดเป็นสตริงว่างเงื่อนไขในของคุณCASEจะไม่เป็นจริงดังนั้นจึงส่งคืนSalaryค่าเสมอ ด้วยเหตุนี้การสืบค้นของคุณจึงเทียบเท่ากับ

SELECT Salary AS SecondHighestSalary
FROM Employee
ORDER BY SecondHighestSalary
LIMIT 1, 1

สิ่งอื่น ๆ:

  1. คุณจำเป็นต้องใช้DESCเพื่อรับเงินเดือนสูงสุดในช่วงเริ่มต้น ดังนั้นแม้ว่าวิธีการของคุณจะได้ผล แต่ก็จะได้รับเงินเดือนต่ำสุดเป็นอันดับสอง
  2. วิธีการของคุณไม่สามารถจัดการกับกรณีที่พนักงานหลายคนถูกผูกติดกับเงินเดือนสูงสุด LIMIT 1, 1จะส่งคืนแถวที่สองซึ่งจะเป็นหนึ่งในพนักงานที่ผูกไว้

คุณสามารถแก้ปัญหาที่สองโดยใช้แบบสอบถามย่อยที่ลบรายการที่ซ้ำกัน:

SELECT DISTINCT Salary
FROM Employee

ดังนั้นคำถามสุดท้ายอาจเป็น:

SELECT IF(COUNT(*) > 0, MAX(Salary), NULL) AS SecondHighestSalary
FROM (
    SELECT DISTINCT Salary
    FROM Employee
    ORDER BY Salary DESC
    LIMIT 1, 1
) AS x
Strawberry Oct 04 2020 at 06:11

เช่น

 select max(salary) salary 
   from employee 
 where salary not in 
 (select max(salary) from employee)
Runa Oct 04 2020 at 06:45

คุณสามารถใช้วิธีนี้ได้โดยที่หากไม่มีเงินเดือนสูงสุดอันดับสองจะคืนค่า NULL มิฉะนั้นจะคืนเงินเดือนสูงสุดเป็นอันดับสอง

SELECT 
   IFNULL(MIN(Salary) , 'NULL') as SecondHighestSalary
FROM
    Employee
WHERE salary > (SELECT MIN(salary)
                 FROM Employee)

หรือถ้าคุณต้องการ DB default null ให้ลบเงื่อนไข IFNULL

SELECT 
   MIN(Salary) as SecondHighestSalary
FROM
    Employee
WHERE salary > (SELECT MIN(salary)
                 FROM Employee)