一、第二高的薪水
方法一:使用子查询和 LIMIT 子句算法
将不同的薪资按降序排序,然后使用 LIMIT 子句获得第二高的薪资。
SELECT DISTINCT
Salary AS SecondHighestSalary
FROM
Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1
然而,如果没有这样的第二最高工资,这个解决方案将被判断为 “错误答案”,因为本表可能只有一项记录。为了克服这个问题,我们可以将其作为临时表。
SELECT
(SELECT DISTINCT
Salary
FROM
Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1) AS SecondHighestSalary
;
为什么使用临时表能解决null值问题?
select NULL
#返回null值
方法二:使用 IFNULL 和 LIMIT 子句
解决 “NULL” 问题的另一种方法是使用 “IFNULL” 函数,如下所示。
SELECT
IFNULL(
(SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1),
NULL) AS SecondHighestSalary
IFNULL(expr1,expr2)的用法:
假如expr1 不为 NULL,则 IFNULL() 的返回值为 expr1; 否则其返回值为 expr2
方法三:第二大的值为<最大值
select max(Salary) SecondHighestSalary
from Employee
where Salary < (select max(Salary) from Employee)
二、超过经理收入的员工
select e2.Name Employee
from Employee e1 left join Employee e2
on e1.Id = e2.ManagerId
where e1.Salary < e2. Salary
三、查找重复的电子邮箱
解法1:(自连接之后去除重复id用where筛选)
select distinct a.Email
from Person a inner join Person b
on a.Email = b.Email
where a.Id != b.Id
解法2:
select email from person group by email having count(email)>1
sql优化——count(1)、count(*)与count(列名)的区别
解法3:
select email
from(select count(1) as t,email
from person
group by email) r
where r.t>1;
四、从不订购的客户
解法一:连接,用is null 判断空值
select c.Name Customers
from Orders o right join Customers c
on o.CustomerId = c.Id
where o.Id is null;
解法二:用not in
select c.Name as Customers
from Customers c
where c.Id not in (select distinct o.CustomerId
from Orders o);
解法三:用exists
exists用法解释
select c.Name as Customers
from Customers c
where not exists (select 1 from Orders o
where o.CustomerId = c.Id);
五、删除重复的电子邮箱
删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。
思路:删除重复的电子邮箱,并保存id最小的那个, from person p1,person p2 相当于两个person表, 当p1中的email与p2表中的email相等并且p1.Id>p2.Id 那么删除p1表中的这条重复的email保留id最小的那个email信息
delete
p1
from person p1,
person p2
where
p1.Email = p2.Email
and
p1.Id > p2.Id
六、上升的温度
来查找与之前(昨天的)日期相比温度更高的所有日期的 id 。返回结果不要求顺序 。
SELECT DATEDIFF('2008-12-30','2008-12-29') AS DiffDate 结果为1;
SELECT DATEDIFF('2008-12-29','2008-12-30') AS DiffDate 结果为-1。
解法一:使用datediff
select a.Id
from Weather as a join Weather as b
on dateDiff(a.RecordDate,b.RecordDate) = 1
and a.Temperature > b.Temperature
解法二:
mysql 中 DATE_ADD函数和 DATE_SUB函数用法
select w1.id id
from Weather w1
left join Weather w2
on w1.recordDate = date_add(w2.recordDate, interval 1 day)
where w1.Temperature > w2.Temperature
七、超过5名学生的课
注意有同学是重修
select class
from courses
group by class
having count(distinct student) >= 5
八、有趣的电影
找出所有影片描述为非 boring (不无聊) 的并且 id 为奇数 的影片,结果请按等级 rating 排列。
select
id
,movie
,description
,rating
from cinema
where not description = 'boring'
and id % 2 = 1
order by rating desc
奇数:
id % 2 = 1
mod(id,2)=1
位运算:id & 1
位运算技巧总结
九、变更性别
给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求只使用一个更新(Update)语句,并且没有中间的临时表。
注意,您必只能写一个 Update 语句,请不要编写任何 Select 语句。
解法一:用case when
update salary
set sex = (
case sex when 'm' then 'f' else 'm' end
解法二:用if
update salary set sex = if(sex='m','f','m');
十、重新格式化部门表
编写一个 SQL 查询来重新格式化表,使得新的表中有一个部门 id 列和一些对应 每个月 的收入(revenue)列。
查询结果格式如下面的示例所示:
Department 表:
±-----±--------±------+
| id | revenue | month |
±-----±--------±------+
| 1 | 8000 | Jan |
| 2 | 9000 | Jan |
| 3 | 10000 | Feb |
| 1 | 7000 | Feb |
| 1 | 6000 | Mar |
±-----±--------±------+
查询得到的结果表:
±-----±------------±------------±------------±----±------------+
| id | Jan_Revenue | Feb_Revenue | Mar_Revenue | … | Dec_Revenue |
±-----±------------±------------±------------±----±------------+
| 1 | 8000 | 7000 | 6000 | … | null |
| 2 | 9000 | null | null | … | null |
| 3 | null | 10000 | null | … | null |
±-----±------------±------------±------------±----±------------+
解法一:用case when
select
id
, sum(case `month` when 'Jan' then revenue else null end) as Jan_Revenue
, sum(case `month` when 'Feb' then revenue else null end) as Feb_Revenue
, sum(case `month` when 'Mar' then revenue else null end) as Mar_Revenue
, sum(case `month` when 'Apr' then revenue else null end) as Apr_Revenue
, sum(case `month` when 'May' then revenue else null end) as May_Revenue
, sum(case `month` when 'Jun' then revenue else null end) as Jun_Revenue
, sum(case `month` when 'Jul' then revenue else null end) as Jul_Revenue
, sum(case `month` when 'Aug' then revenue else null end) as Aug_Revenue
, sum(case `month` when 'Sep' then revenue else null end) as Sep_Revenue
, sum(case `month` when 'Oct' then revenue else null end) as Oct_Revenue
, sum(case `month` when 'Nov' then revenue else null end) as Nov_Revenue
, sum(case `month` when 'Dec' then revenue else null end) as Dec_Revenue
from Department group by id
解法二:用if
select distinct id,
sum(IF(month="Jan",revenue,null)) as Jan_Revenue,
sum(IF(month="Feb",revenue,null)) as Feb_Revenue,
sum(IF(month="Mar",revenue,null)) as Mar_Revenue,
sum(IF(month="Apr",revenue,null)) as Apr_Revenue,
sum(IF(month="May",revenue,null)) as May_Revenue,
sum(IF(month="Jun",revenue,null)) as Jun_Revenue,
sum(IF(month="Jul",revenue,null)) as Jul_Revenue,
sum(IF(month="Aug",revenue,null)) as Aug_Revenue,
sum(IF(month="Sep",revenue,null)) as Sep_Revenue,
sum(IF(month="Oct",revenue,null)) as Oct_Revenue,
sum(IF(month="Nov",revenue,null)) as Nov_Revenue,
sum(IF(month="Dec",revenue,null)) as Dec_Revenue
from Department group by id order by id;
注:单独地使用group by (不加聚合函数),只能显示出每组记录的第一条记录。但凡使用group by,前面一定要有聚合函数(MAX /MIN / SUM /AVG / COUNT)
所有资料来源均来源于网络,本文章仅用于个人学习整理。