180. 连续出现的数字
表:Logs
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| num | varchar |
+-------------+---------+
id 是这个表的主键。
编写一个 SQL 查询,查找所有至少连续出现三次的数字。
返回的结果表中的数据可以按 任意顺序 排列。
查询结果格式如下面的例子所示:
示例 1:
输入:
Logs 表:
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
输出:
Result 表:
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+
解释:1 是唯一连续出现至少三次的数字。
题解
思路一:使用前函数和后函数
# Write your MySQL query statement below
SELECT
distinct num ConsecutiveNums
FROM (
SELECT
num,
LAG(num, 1, null) over (order by id) lag_num,
LEAD(num, 1, null) over (order by id) lead_num
FROM logs
) l
WHERE
l.Num = l.lag_num and l.Num = l.lead_num;
思路二:使用if的形式
#①首先遍历一遍整张表,找出每个数字的连续重复次数
#具体方法为:
#初始化两个变量,一个为pre,记录上一个数字;一个为count,记录上一个数字已经连续出现的次数。
#然后调用if()函数,如果pre和当前行数字相同,count加1极为连续出现的次数;如果不同,意味着重新开始一个数字,count重新从1开始。
#最后,将当前的Num数字赋值给pre,开始下一行扫描。
select
Num, #当前的Num 数字
if(@pre=Num,@count := @count+1,@count := 1) as nums, #判断 和 计数
@pre:=Num #将当前Num赋值给pre
from Logs as l ,
(select @pre:= null,@count:=1) as pc #这里需要别名
#上面这段代码执行结果就是一张三列为Num,count as nums,pre的表。
#②将上面表的结果中,重复次数大于等于3的数字选出,再去重即为连续至少出现三次的数字。
select
distinct Num as ConsecutiveNums
from
(select Num,
if(@pre=Num,@count := @count+1,@count := 1) as nums,
@pre:=Num
from Logs as l ,
(select @pre:= null,@count:=1) as pc
) as n
where nums >=3;
#注意:pre初始值最好不要赋值为一个数字,因为不确定赋值的数字是否会出现在测试表中。
最后题解是
# Write your MySQL query statement below
select
distinct Num as ConsecutiveNums
from
(select Num,
if(@pre=Num,@count := @count+1,@count := 1) as nums,
@pre:=Num
from Logs as l ,
(select @pre:= null,@count:=1) as pc
) as n
where nums >=3;
思路三lead()函数一步搞定
# Write your MySQL query statement below
select distinct num as ConsecutiveNums from
(
select num,lead(num,1)over()as num1,lead(num,2)over()as num2
from logs
) as c
where c.num = c.num1 and c.num1 = c.num2
181. 超过经理收入的员工
表:Employee
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
| salary | int |
| managerId | int |
+-------------+---------+
Id是该表的主键。
该表的每一行都表示雇员的ID、姓名、工资和经理的ID。
编写一个SQL查询来查找收入比经理高的员工。
以 任意顺序 返回结果表。
查询结果格式如下所示。
示例 1:
+----+-------+--------+-----------+
| id | name | salary | managerId |
+----+-------+--------+-----------+
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | Null |
| 4 | Max | 90000 | Null |
+----+-------+--------+-----------+
输出:
+----------+
| Employee |
+----------+
| Joe |
+----------+
解释: Joe 是唯一挣得比经理多的雇员。
题解:
考虑到自查询,就是如果这个人id和managerId一样,他就不是manager,就过滤薪资比经理高就行
SELECT a.name Employee
FROM
Employee a
JOIN
Employee b
ON
a.managerId = b.id
AND a.salary > b.salary;
182. 查找重复的电子邮箱
编写一个 SQL 查询,查找 Person
表中所有重复的电子邮箱。
示例:
+----+---------+
| Id | Email |
+----+---------+
| 1 | a@b.com |
| 2 | c@d.com |
| 3 | a@b.com |
+----+---------+
根据以上输入,你的查询应返回以下结果:
+---------+
| Email |
+---------+
| a@b.com |
+---------+
**说明:**所有电子邮箱都是小写字母。
题解:
方式一:直接使用group by 和having过滤
# Write your MySQL query statement below
SELECT Email
FROM Person
GROUP BY Email
HAVING COUNT(Email) != 1;
方法二:先在计数email作为内表,然后再使用where过滤count>1
# Write your MySQL query statement below
select p.Email from (select Email,Count(Email) num from Person group by Email ) p where num > 1;
也可以换一种形式哈哈
就是把内表提到with里面来
# Write your MySQL query statement below
with p as (select Email,Count(Email) num from Person group by Email)
select p.Email from p where p.num > 1;
183. 从不订购的客户
某网站包含两个表,Customers
表和 Orders
表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。
Customers
表:
+----+-------+
| Id | Name |
+----+-------+
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
+----+-------+
Orders
表:
+----+------------+
| Id | CustomerId |
+----+------------+
| 1 | 3 |
| 2 | 1 |
+----+------------+
例如给定上述表格,你的查询应返回:
+-----------+
| Customers |
+-----------+
| Henry |
| Max |
+-----------+
题解
建个表
create table customers (
id int primary key auto_increment,
name varchar(255)
);
insert into customers (name) values('Joe'), ('Henry'), ('Sam'), ('Max');
create table orders (
id int primary key auto_increment,
customerId int
);
insert into orders (customerId) values(3),(1);
题解一
左连接+isnull(字段)
# Write your MySQL query statement below
SELECT Name "Customers"
FROM Customers c
LEFT JOIN Orders o
ON c.Id=o.CustomerId
WHERE isnull(o.CustomerId)
题解二
not in (子查询)
# Write your MySQL query statement below
SELECT Name "Customers"
FROM Customers c
WHERE c.Id not in (
SELECT CustomerId
FROM Orders
);
题解三
not exsits
# Write your MySQL query statement below
select name as "customers" from customers where not exists (
select customerId from orders where customerId = customers.id
);