176. Second Highest Salary--MAX,UNION,LIMIT

题目:

Write a SQL query to get the second highest salary from the Employee table.

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

For example, given the above Employee table, the query should return 200 as the second highest salary. If there is no second highest salary, then the query should return null.

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

没有想法……看了大家分享的答案发现自己还是没有数学思维

SELECT max(Salary)
FROM Employee
WHERE Salary < (SELECT max(Salary) FROM Employee)



解释:Using max() will return a NULL if the value doesn't exist. So there is no need to UNION a NULL. Of course, if the second highest value is guaranteed to exist, using LIMIT 1,1 will be the best answer.

使用MAX()在没有结果时可以返回空值

如果第二高的薪水可以确定存在的话,使用LIMIT 1,1 最优


这种方法大概只适用于求第二 如果要求返回3rd 4th就很不实用



另一种方法是使用Limit和Offset 都是没学过的函数TT

SELECT Salary FROM Employee GROUP BY Salary
UNION ALL (SELECT NULL AS Salary)
ORDER BY Salary DESC LIMIT 1 OFFSET 1;

MySQL中Limit后面的数字限制了我们返回数据的个数,Offset是偏移量

那么如果我们想找第二高薪水,我们首先可以先对薪水进行降序排列,然后我们将Offset设为1,那么就是从第二个开始,也就是第二高薪水,然后我们将Limit设为1,就是只取出第二高薪水,如果将Limit设为2,那么就将第二高和第三高薪水都取出来


SQL UNION 操作符

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL
以下是完整的C++代码: ```c++ #include <iostream> #include <cstring> #include <algorithm> using namespace std; struct Student{ int id; string name; int score[3]; double average; bool fail; }stu[4]; bool cmp(Student a, Student b){ return a.average > b.average; } int main(){ int lesson[3]; for(int i=0; i<3; i++){ cin >> lesson[i]; } for(int i=0; i<4; i++){ cin >> stu[i].id >> stu[i].name >> stu[i].score[0] >> stu[i].score[1] >> stu[i].score[2]; stu[i].average = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0; if(stu[i].average < 60){ stu[i].fail = true; } else{ stu[i].fail = false; } } double max_avg = -1, min_avg = 101; int max_pos = -1, min_pos = -1; for(int i=0; i<4; i++){ if(stu[i].average > max_avg){ max_avg = stu[i].average; max_pos = i; } if(stu[i].average < min_avg){ min_avg = stu[i].average; min_pos = i; } } cout << "Student " << stu[max_pos].name << " got the highest average score as " << fixed << setprecision(4) << max_avg << endl; cout << "Student " << stu[min_pos].name << " got the lowest average score as " << fixed << setprecision(4) << min_avg << endl; sort(stu, stu+4, cmp); for(int i=0; i<4; i++){ cout << "Student id:" << stu[i].id << " Student name:" << stu[i].name << endl; cout << "lesson_id " << lesson[0] << " " << lesson[1] << " " << lesson[2] << " " << "Average" << endl; cout << "scores " << stu[i].score[0] << " " << stu[i].score[1] << " " << stu[i].score[2] << " " << fixed << setprecision(4) << stu[i].average << endl; if(stu[i].fail){ cout << "The student failed." << endl; } else{ cout << "The student didn't fail." << endl; } cout << "------华丽的分割线--------" << endl; } return 0; } ``` 代码思路: 1. 定义结构体 `Student`,存储学生的信息; 2. 读入三门课的课程号; 3. 逐次读入四位学生的信息,计算出平均分,并判断是否不及格; 4. 找出最平均分和最低平均分的学生位置; 5. 对学生数组进行排序,按照平均分从到低排序; 6. 按照输出格式输出最分、最低分和排序后的结果。 注意事项: 1. 使用 `setprecision()` 函数控制浮点数的精度; 2. 本题中的分隔符是中文的“华丽的分割线”,需要注意输出时的中英文符号混用问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值