【力扣 + 牛客 | SQL题 | 每日5题】牛客SQL热题204,201,215
1. 力扣1126:查询活跃业务
1.1 题目:
事件表:Events
+---------------+---------+ | Column Name | Type | +---------------+---------+ | business_id | int | | event_type | varchar | | occurrences | int | +---------------+---------+ (business_id, event_type) 是这个表的主键(具有唯一值的列的组合)。 表中的每一行记录了某种类型的事件在某些业务中多次发生的信息。
平均活动 是指有特定 event_type
的具有该事件的所有公司的 occurrences
的均值。
活跃业务 是指具有 多个 event_type
的业务,它们的 occurrences
严格大于 该事件的平均活动次数。
写一个解决方案,找到所有 活跃业务。
以 任意顺序 返回结果表。
结果格式如下所示。
示例 1:
输入: Events table: +-------------+------------+-------------+ | business_id | event_type | occurrences | +-------------+------------+-------------+ | 1 | reviews | 7 | | 3 | reviews | 3 | | 1 | ads | 11 | | 2 | ads | 7 | | 3 | ads | 6 | | 1 | page views | 3 | | 2 | page views | 12 | +-------------+------------+-------------+ 输出: +-------------+ | business_id | +-------------+ | 1 | +-------------+ 解释: 每次活动的平均活动可计算如下: - 'reviews': (7+3)/2 = 5 - 'ads': (11+7+6)/3 = 8 - 'page views': (3+12)/2 = 7.5 id=1 的业务有 7 个 'reviews' 事件(多于 5 个)和 11 个 'ads' 事件(多于 8 个),所以它是一个活跃的业务。
1.2 思路:
使用ans字段判断每组记录的平均值是否要比公司的均值要大.
1.3 题解:
-- 先求出所有公司的各个event_type业务的平均值
with tep1 as (
select
event_type, avg(occurrences) avgs
from Events
group by event_type
), tep2 as (
-- 然后判断每组记录的平均值是否比公司的均值要大
-- 如果大的话ans字段的值为1,否则为0
select business_id ,
case when avg(occurrences) > (select avgs from tep1 t2 where t1.event_type = t2.event_type)
and avg(occurrences) > 0
then 1
else 0
end ans
from Events t1
group by business_id, event_type
)
-- where过滤掉ans不为1 的记录
-- having过滤不是活跃业务的记录
select business_id
from tep2
where ans = 1
group by business_id
having count(*) >= 2
2. 力扣1069:产品销售分析2
2.1 题目:
销售表:Sales
+-------------+-------+ | Column Name | Type | +-------------+-------+ | sale_id | int | | product_id | int | | year | int | | quantity | int | | price | int | +-------------+-------+ sale_id 是这个表的主键(具有唯一值的列)。 product_id 是 Product 表的外键(reference 列)。 该表的每一行显示产品product_id在某一年的销售情况。 请注意价格是每单位的。
产品表:Product
+--------------+---------+ | Column Name | Type | +--------------+---------+ | product_id | int | | product_name | varchar | +--------------+---------+ product_id 是这个表的主键(具有唯一值的列)。 该表的每一行表示每种产品的产品名称。
编写解决方案,统计每个产品的销售总量。
返回结果表 无顺序要求 。
结果格式如下例子所示。
示例 1:
输入:
Sales
表:
+---------+------------+------+----------+-------+
| sale_id | product_id | year | quantity | price |
+---------+------------+------+----------+-------+
| 1 | 100 | 2008 | 10 | 5000 |
| 2 | 100 | 2009 | 12 | 5000 |
| 7 | 200 | 2011 | 15 | 9000 |
+---------+------------+------+----------+-------+
Product 表:
+------------+--------------+
| product_id | product_name |
+------------+--------------+
| 100 | Nokia |
| 200 | Apple |
| 300 | Samsung |
+------------+--------------+
输出:
+--------------+----------------+
| product_id | total_quantity |
+--------------+----------------+
| 100 | 22 |
| 200 | 15 |
+--------------+----------------+
2.2 思路:
看SQL即可。
2.3 题解:
with tep as (
select t1.product_id, quantity
from Sales t1
join Product t2
on t1.product_id = t2.product_id
)
select product_id, sum(quantity) total_quantity
from tep
group by product_id
3. 牛客SQL热题204:获取所有非manager的员工emp_no
3.1 题目:
描述
有一个员工表employees简况如下:
emp_no | birth_date | first_name | last_name | gender | hire_date |
10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 |
10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 |
10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 |
有一个部门领导表dept_manager简况如下:
dept_no | emp_no | from_date | to_date |
d001 | 10002 | 1996-08-03 | 9999-01-01 |
d002 | 10003 | 1990-08-05 | 9999-01-01 |
请你找出所有非部门领导的员工emp_no,以上例子输出:
emp_no |
10001 |
示例1
输入:
drop table if exists `dept_manager` ;
drop table if exists `employees` ;
CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
INSERT INTO dept_manager VALUES('d001',10002,'1996-08-03','9999-01-01');
INSERT INTO dept_manager VALUES('d002',10003,'1990-08-05','9999-01-01');
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','1986-06-26');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21');
INSERT INTO employees VALUES(10003,'1959-12-03','Parto','Bamford','M','1986-08-28');
复制输出:
10001
3.2 思路:
看SQL
3.3 题解:
select emp_no
from employees
where emp_no not in (
select emp_no
from dept_manager
)
4. 牛客SQL热题201:查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t
4.1 题目:
描述
有一个薪水表,salaries简况如下:
emp_no | salary | from_date | to_date |
10001 | 60117 | 1986-06-26 | 1987-06-26 |
10001 | 62102 | 1987-06-26 | 1988-06-25 |
10001 | 66074 | 1988-06-25 | 1989-06-25 |
10001 | 66596 | 1989-06-25 | 1990-06-25 |
10001 | 66961 | 1990-06-25 | 1991-06-25 |
10001 | 71046 | 1991-06-25 | 1992-06-24 |
10001 | 74333 | 1992-06-24 | 1993-06-24 |
10001 | 75286 | 1993-06-24 | 1994-06-24 |
10001 | 75994 | 1994-06-24 | 1995-06-24 |
10001 | 76884 | 1995-06-24 | 1996-06-23 |
10001 | 80013 | 1996-06-23 | 1997-06-23 |
10001 | 81025 | 1997-06-23 | 1998-06-23 |
10001 | 81097 | 1998-06-23 | 1999-06-23 |
10001 | 84917 | 1999-06-23 | 2000-06-22 |
10001 | 85112 | 2000-06-22 | 2001-06-22 |
10001 | 85097 | 2001-06-22 | 2002-06-22 |
10002 | 72527 | 1996-08-03 | 1997-08-03 |
请你查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t,以上例子输出如下:
emp_no | t |
10001 | 16 |
示例1
输入:
drop table if exists `salaries` ;
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
INSERT INTO salaries VALUES(10001,60117,'1986-06-26','1987-06-26');
INSERT INTO salaries VALUES(10001,62102,'1987-06-26','1988-06-25');
INSERT INTO salaries VALUES(10001,66074,'1988-06-25','1989-06-25');
INSERT INTO salaries VALUES(10001,66596,'1989-06-25','1990-06-25');
INSERT INTO salaries VALUES(10001,66961,'1990-06-25','1991-06-25');
INSERT INTO salaries VALUES(10001,71046,'1991-06-25','1992-06-24');
INSERT INTO salaries VALUES(10001,74333,'1992-06-24','1993-06-24');
INSERT INTO salaries VALUES(10001,75286,'1993-06-24','1994-06-24');
INSERT INTO salaries VALUES(10001,75994,'1994-06-24','1995-06-24');
INSERT INTO salaries VALUES(10001,76884,'1995-06-24','1996-06-23');
INSERT INTO salaries VALUES(10001,80013,'1996-06-23','1997-06-23');
INSERT INTO salaries VALUES(10001,81025,'1997-06-23','1998-06-23');
INSERT INTO salaries VALUES(10001,81097,'1998-06-23','1999-06-23');
INSERT INTO salaries VALUES(10001,84917,'1999-06-23','2000-06-22');
INSERT INTO salaries VALUES(10001,85112,'2000-06-22','2001-06-22');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','1997-08-03');
复制输出:
10001|17
4.2 思路:
太基础了吧。
4.3 题解:
select emp_no, count(*) t
from salaries
group by emp_no
having count(*) > 15
5. 牛客SQL热题215:查找在职员工自入职以来的薪水涨幅情况
5.1 题目:
描述
有一个员工表employees简况如下:
emp_no | birth_date | first_name | last_name | gender | hire_date |
10001 | 1953-09-02 | Georgi | Facello | M | 2001-06-22 |
10002 | 1964-06-02 | Bezalel | Simmel | F | 1999-08-03 |
有一个薪水表salaries简况如下:
emp_no | salary | from_date | to_date |
10001 | 85097 | 2001-06-22 | 2002-06-22 |
10001 | 88958 | 2002-06-22 | 9999-01-01 |
10002 | 72527 | 1999-08-03 | 2000-08-02 |
10002 | 72527 | 2000-08-02 | 2001-08-02 |
请你查找在职员工自入职以来的薪水涨幅情况,给出在职员工编号emp_no以及其对应的薪水涨幅growth,并按照growth进行升序,以上例子输出为
(注: to_date为薪资调整某个结束日期,或者为离职日期,to_date='9999-01-01'时,表示依然在职,无后续调整记录)
emp_no | growth |
10001 | 3861 |
示例1
输入:
drop table if exists `employees` ;
drop table if exists `salaries` ;
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
INSERT INTO employees VALUES(10001,'1953-09-02','Georgi','Facello','M','2001-06-22');
INSERT INTO employees VALUES(10002,'1964-06-02','Bezalel','Simmel','F','1999-08-03');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1999-08-03','2000-08-02');
INSERT INTO salaries VALUES(10002,72527,'2000-08-02','2001-08-02');
复制输出:
10001|3861