目录
方法二:row_number()
1、180连续出现的数字
编写一个 SQL 查询,查找所有至少连续出现三次的数字。返回的结果表中的数据可以按任意顺序排列。
Create table If Not Exists Logs (id int, num int);
Truncate table Logs;
insert into Logs (id, num) values ('1', '1');
insert into Logs (id, num) values ('2', '1');
insert into Logs (id, num) values ('3', '1');
insert into Logs (id, num) values ('4', '2');
insert into Logs (id, num) values ('5', '1');
insert into Logs (id, num) values ('6', '2');
insert into Logs (id, num) values ('7', '2');
SELECT * FROM LOGS;
方法一:自连接查询
由于数据比较少,可以考虑自连接的方式
查找num数据相同,且id差距为1,可用于确定连续次数,且次数较少。
SELECT e1.id, e1.num AS ConsecutiveNums
FROM Logs e1,LOGS e2,LOGS e3
WHERE e1.num=e2.num
AND e2.num=e3.num
AND e1.id-e2.id=1
AND e2.id-e3.id=1;
方法二:row_number()
用于数据较多,连续次数较多
select distinct Num as ConsecutiveNums from(
select Num,(row_number()over(order by Id)-row_number()over(partition by Num order by Id)) as series_id
from Logs) t
group by Num, series_id
having count(1) >= 3;
扩展
row_number()函数的用法:
语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
row_number() OVER (PARTITION BY e1 ORDER BY e2) 表示根据e1分组,在分组内部根据 e2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)
2、181超过经理收入的员工
编写一个SQL查询来查找收入比经理高的员工。以任意顺序返回结果表。
Create table If Not Exists Employee1 (id int, name varchar(255), salary int, managerId int);
Truncate table Employee1;
insert into Employee1 (id, name, salary, managerId) values ('1', 'Joe', '70000', '3');
insert into Employee1 (id, name, salary, managerId) values ('2', 'Henry', '80000', '4');
insert into Employee1 (id, name, salary, managerId) values ('3', 'Sam', '60000', NULL);
insert into Employee1 (id, name, salary, managerId) values ('4', 'Max', '90000', NULL);
SELECT * FROM employee1;
方法一:where语句
使用where语句,自连接查询,从两个表中使用select语句会产生笛卡尔乘积,用where语句筛选行。
SELECT e1.name as employee
FROM employee1 e1,employee e2
WHERE e1.managerId=e2.id
and e1.salary>e2.salary
方法二:join语句
使用join语句,连接同一个表,用第一个表managerId和第二个表的id来连接
SELECT e1.name as employee
FROM employee1 as e1
JOIN employee1 as e2
ON e1.managerId=e2.id
and e1.salary>e2.salary;
3、182查找重复的电子邮箱
编写一个 SQL 查询,查找 Person
表中所有重复的电子邮箱。
Create table If Not Exists Person1 (id int, email varchar(255));
Truncate table Person1;
insert into Person1 (id, email) values ('1', '[email protected]');
insert into Person1 (id, email) values ('2', '[email protected]');
insert into Person1 (id, email) values ('3', '[email protected]');
SELECT * FROM Person1;
与上题解题思路一致
方法一:where语句
方法二:join语句
方法三:使用group by和临时表
方法四:调用group by和having语句
#方法一:
SELECT distinct e1.email
FROM person1 e1,person1 e2
WHERE e1.email=e2.email
AND e1.id>e2.id;
#方法二:
SELECT distinct e1.email FROM person1 as e1
join person1 as e2
ON e1.email=e2.email
AND e1.id>e2.id;
#方法三
select distinct Email
from (select email,count(email) as num from person1 group by email) as e1
where num>1;
方法四:
select Email from person1 g
roup by Email
having count(email)>1;
4、183从不订购的客户
某网站包含两个表,Customers
表和 Orders
表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。
Create table If Not Exists Customers (id int, name varchar(255));
Create table If Not Exists Orders (id int, customerId int);
Truncate table Customers;
insert into Customers (id, name) values ('1', 'Joe');
insert into Customers (id, name) values ('2', 'Henry');
insert into Customers (id, name) values ('3', 'Sam');
insert into Customers (id, name) values ('4', 'Max');
Truncate table Orders;
insert into Orders (id, customerId) values ('1', '3');
insert into Orders (id, customerId) values ('2', '1');
SELECT * FROM Customers;
SELECT * FROM Orders;
观察两个数据表可以发现,Customers.id与Orders.customerId关联,可通过子查询查到订购过的客户名单,用not in 子句排除订购过的客户名单,得到从不订购的客户名单。
select name as 'Customers' from Customers
where Customers.id
not in(select CustomerId from Orders)
错误案例:通过子查询查询购买客户的名字,用not in子句排除订购过的客户名单,得到从不订购的客户名单。
错误原因:客户id是唯一的,客户名字可能重名。
select name as Customers from Customers
where name
NOT in (select name from Customers join Orders
on Customers.id=Orders.CustomerId)
转载说明:题目出自LeetCode官网