1.买下所有产品的客户
SQL
Create table If Not Exists Customer (customer_id int, product_key int);
Create table Product (product_key int);
Truncate table Customer;
insert into Customer (customer_id, product_key) values ('1', '5');
insert into Customer (customer_id, product_key) values ('2', '6');
insert into Customer (customer_id, product_key) values ('3', '5');
insert into Customer (customer_id, product_key) values ('3', '6');
insert into Customer (customer_id, product_key) values ('1', '6');
Truncate table Product;
insert into Product (product_key) values ('5');
insert into Product (product_key) values ('6');
Customer
表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| customer_id | int |
| product_key | int |
+-------------+---------+
该表可能包含重复的行。
customer_id 不为 NULL。
product_key 是 Product 表的外键(reference 列)。
Product
表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_key | int |
+-------------+---------+
product_key 是这张表的主键(具有唯一值的列)。
编写解决方案,报告 Customer
表中购买了 Product
表中所有产品的客户的 id。
返回结果表 无顺序要求 。
返回结果格式如下所示。
示例 1:
输入:
Customer 表:
+-------------+-------------+
| customer_id | product_key |
+-------------+-------------+
| 1 | 5 |
| 2 | 6 |
| 3 | 5 |
| 3 | 6 |
| 1 | 6 |
+-------------+-------------+
Product 表:
+-------------+
| product_key |
+-------------+
| 5 |
| 6 |
+-------------+
输出:
+-------------+
| customer_id |
+-------------+
| 1 |
| 3 |
+-------------+
解释:
购买了所有产品(5 和 6)的客户的 id 是 1 和 3 。
思路
这里有些取巧了
1.首先会过滤掉Customer表中不在Product表中的product_key,
2.然后再进行分组和计数,保证每个客户购买的产品种类数量等于Product表中产品的总数,从而得到符合条件的客户的customer_id
题解
select distinct customer_id
from Customer
group by customer_id
having count(distinct product_key) = (select count(*) from Product)
2.产品销售分析
SQL
Create table If Not Exists Sales (sale_id int, product_id int, year int, quantity int, price int);
Create table If Not Exists Product (product_id int, product_name varchar(10));
Truncate table Sales;
insert into Sales (sale_id, product_id, year, quantity, price) values ('1', '100', '2008', '10', '5000');
insert into Sales (sale_id, product_id, year, quantity, price) values ('2', '100', '2009', '12', '5000');
insert into Sales (sale_id, product_id, year, quantity, price) values ('7', '200', '2011', '15', '9000');
Truncate table Product;
insert into Product (product_id, product_name) values ('100', 'Nokia');
insert into Product (product_id, product_name) values ('200', 'Apple');
insert into Product (product_id, product_name) values ('300', 'Samsung');
销售表 Sales
:
+-------------+-------+
| Column Name | Type |
+-------------+-------+
| sale_id | int |
| product_id | int |
| year | int |
| quantity | int |
| price | int |
+-------------+-------+
(sale_id, year) 是这张表的主键(具有唯一值的列的组合)。
product_id 是产品表的外键(reference 列)。
这张表的每一行都表示:编号 product_id 的产品在某一年的销售额。
请注意,价格是按每单位计的。
产品表 Product
:
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| product_id | int |
| product_name | varchar |
+--------------+---------+
product_id 是这张表的主键(具有唯一值的列)。
这张表的每一行都标识:每个产品的 id 和 产品名称。
编写解决方案,选出每个售出过的产品 第一年 销售的 产品 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 | first_year | quantity | price |
+------------+------------+----------+-------+
| 100 | 2008 | 10 | 5000 |
| 200 | 2011 | 15 | 9000 |
+------------+------------+----------+-------+
说明:
根据题意,选出每个售出过的产品 第一年销售的产品id、年份、数量和价格。
编号 1和编号8都应该显示
思路
1.筛选最小年份的产品id、年份
2.使用group by product_id 分组,min()函数获取最小年份数据 表a
3.Sales表 in 表a
题解
方式一:
select product_id ,year first_year,quantity,price
from Sales
where (product_id,`year`) in
(
-- 获取第一年的产品
select product_id,min(year) year
from Sales
group by product_id
);
方式二:
select product_id, year as first_year, quantity, price
from(
select *, rank() over (partition by product_id order by year) as rk
from Sales
) t1
where t1.rk = 1
3.市场分析
SQL
Create table If Not Exists Users (user_id int, join_date date, favorite_brand varchar(10));
Create table If Not Exists Orders (order_id int, order_date date, item_id int, buyer_id int, seller_id int);
Create table If Not Exists Items (item_id int, item_brand varchar(10));
Truncate table Users;
insert into Users (user_id, join_date, favorite_brand) values ('1', '2018-01-01', 'Lenovo');
insert into Users (user_id, join_date, favorite_brand) values ('2', '2018-02-09', 'Samsung');
insert into Users (user_id, join_date, favorite_brand) values ('3', '2018-01-19', 'LG');
insert into Users (user_id, join_date, favorite_brand) values ('4', '2018-05-21', 'HP');
Truncate table Orders;
insert into Orders (order_id, order_date, item_id, buyer_id, seller_id) values ('1', '2019-08-01', '4', '1', '2');
insert into Orders (order_id, order_date, item_id, buyer_id, seller_id) values ('2', '2018-08-02', '2', '1', '3');
insert into Orders (order_id, order_date, item_id, buyer_id, seller_id) values ('3', '2019-08-03', '3', '2', '3');
insert into Orders (order_id, order_date, item_id, buyer_id, seller_id) values ('4', '2018-08-04', '1', '4', '2');
insert into Orders (order_id, order_date, item_id, buyer_id, seller_id) values ('5', '2018-08-04', '1', '3', '4');
insert into Orders (order_id, order_date, item_id, buyer_id, seller_id) values ('6', '2019-08-05', '2', '2', '4');
Truncate table Items;
insert into Items (item_id, item_brand) values ('1', 'Samsung');
insert into Items (item_id, item_brand) values ('2', 'Lenovo');
insert into Items (item_id, item_brand) values ('3', 'LG');
insert into Items (item_id, item_brand) values ('4', 'HP');
表: Users
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| user_id | int |
| join_date | date |
| favorite_brand | varchar |
+----------------+---------+
user_id 是此表主键(具有唯一值的列)。
表中描述了购物网站的用户信息,用户可以在此网站上进行商品买卖。
表: Orders
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| order_id | int |
| order_date | date |
| item_id | int |
| buyer_id | int |
| seller_id | int |
+---------------+---------+
order_id 是此表主键(具有唯一值的列)。
item_id 是 Items 表的外键(reference 列)。
(buyer_id,seller_id)是 User 表的外键。
表:Items
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| item_id | int |
| item_brand | varchar |
+---------------+---------+
item_id 是此表的主键(具有唯一值的列)。
编写解决方案找出每个用户的注册日期和在 2019
年作为买家的订单总数。
以 任意顺序 返回结果表。
查询结果格式如下。
示例 1:
输入:
Users 表:
+---------+------------+----------------+
| user_id | join_date | favorite_brand |
+---------+------------+----------------+
| 1 | 2018-01-01 | Lenovo |
| 2 | 2018-02-09 | Samsung |
| 3 | 2018-01-19 | LG |
| 4 | 2018-05-21 | HP |
+---------+------------+----------------+
Orders 表:
+----------+------------+---------+----------+-----------+
| order_id | order_date | item_id | buyer_id | seller_id |
+----------+------------+---------+----------+-----------+
| 1 | 2019-08-01 | 4 | 1 | 2 |
| 2 | 2018-08-02 | 2 | 1 | 3 |
| 3 | 2019-08-03 | 3 | 2 | 3 |
| 4 | 2018-08-04 | 1 | 4 | 2 |
| 5 | 2018-08-04 | 1 | 3 | 4 |
| 6 | 2019-08-05 | 2 | 2 | 4 |
+----------+------------+---------+----------+-----------+
Items 表:
+---------+------------+
| item_id | item_brand |
+---------+------------+
| 1 | Samsung |
| 2 | Lenovo |
| 3 | LG |
| 4 | HP |
+---------+------------+
输出:
+-----------+------------+----------------+
| buyer_id | join_date | orders_in_2019 |
+-----------+------------+----------------+
| 1 | 2018-01-01 | 1 |
| 2 | 2018-02-09 | 2 |
| 3 | 2018-01-19 | 0 |
| 4 | 2018-05-21 | 0 |
+-----------+------------+----------------+
思路
1.筛选order表中2019年的数据
2.连接user表
3.group by user_id 进行分组
4.根据count(buyer_id)统计订单数量
题解
select user_id buyer_id ,join_date,count(buyer_id) orders_in_2019
from
(
select *
from Users u
left join Orders o
on u.user_id=o.buyer_id and date_format(o.order_date,"%Y")='2019'
)t
group by user_id
4.指定日期的产品价格
SQL
Create table If Not Exists Products (product_id int, new_price int, change_date date);
Truncate table Products;
INSERT INTO `ry`.`products` (`product_id`, `new_price`, `change_date`) VALUES (1, 20, '2019-08-14');
INSERT INTO `ry`.`products` (`product_id`, `new_price`, `change_date`) VALUES (2, 50, '2019-08-14');
INSERT INTO `ry`.`products` (`product_id`, `new_price`, `change_date`) VALUES (1, 30, '2019-08-15');
INSERT INTO `ry`.`products` (`product_id`, `new_price`, `change_date`) VALUES (1, 35, '2019-08-16');
INSERT INTO `ry`.`products` (`product_id`, `new_price`, `change_date`) VALUES (2, 65, '2019-08-17');
INSERT INTO `ry`.`products` (`product_id`, `new_price`, `change_date`) VALUES (3, 20, '2019-08-18');
INSERT INTO `ry`.`products` (`product_id`, `new_price`, `change_date`) VALUES (1, 25, '2019-08-16');
产品数据表: Products
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| product_id | int |
| new_price | int |
| change_date | date |
+---------------+---------+
(product_id, change_date) 是此表的主键(具有唯一值的列组合)。
这张表的每一行分别记录了 某产品 在某个日期 更改后 的新价格。
编写一个解决方案,找出在 2019-08-16
时全部产品的价格,假设所有产品在修改前的价格都是 10
。
以 任意顺序 返回结果表。
结果格式如下例所示。
示例 1:
输入:
Products 表:
+------------+-----------+-------------+
| product_id | new_price | change_date |
+------------+-----------+-------------+
| 1 | 20 | 2019-08-14 |
| 2 | 50 | 2019-08-14 |
| 1 | 30 | 2019-08-15 |
| 1 | 35 | 2019-08-16 |
| 2 | 65 | 2019-08-17 |
| 3 | 20 | 2019-08-18 |
+------------+-----------+-------------+
输出:
+------------+-------+
| product_id | price |
+------------+-------+
| 2 | 50 |
| 1 | 35 |
| 1 | 25 |
| 3 | 10 |
+------------+-------+
思路
1.根据条件查询`2019-08-16` 时全部产品的产品id,日期
2.where change_date <= '2019-08-16' 筛选
3.利用产品id分组 group by product_id
4.max(change_date)获取最近日期
5.使用子查询获取对应价格
6.连接一个只有产品id的表,获取之前没有的产品价格,设置为10
题解
方式一:
select p1.product_id, ifnull(p2.new_price, 10) as price
from (
select distinct product_id
from products
) as p1 -- 所有的产品
left join (
select product_id, new_price
from products
where (product_id, change_date) in (
select product_id, max(change_date)
from products
where change_date <= '2019-08-16'
group by product_id
)
) as p2 -- 在 2019-08-16 之前有过修改的产品和最新的价格
on p1.product_id = p2.product_id
方式二:
SELECT DISTINCT product_id, IF(filter_date IS NULL, 10, new_price) AS price
FROM (
SELECT *, RANK() OVER(PARTITION BY product_id ORDER BY filter_date DESC) AS RANKING
FROM (
SELECT *, IF(change_date > '2019-08-16', NULL, change_date) AS filter_date
FROM Products
) T
) TT
WHERE TT.RANKING = 1
方式三:(这里我的数据测试是可以的,但是显示不通过。仅供参考)
SELECT product_id,price
FROM
(
SELECT
product_id,
rank() over ( PARTITION BY product_id ORDER BY cur_date desc) AS rk,
IF
( isnull( cur_date ), '10', new_price ) price
FROM
( SELECT product_id, new_price, change_date, IF ( change_date > '2019-08-16', NULL, change_date ) AS cur_date FROM Products ) t1
)t
where rk=1
5.即时食物配送
SQL
Create table If Not Exists Delivery (delivery_id int, customer_id int, order_date date, customer_pref_delivery_date date);
Truncate table Delivery;
insert into Delivery (delivery_id, customer_id, order_date, customer_pref_delivery_date) values ('1', '1', '2019-08-01', '2019-08-02');
insert into Delivery (delivery_id, customer_id, order_date, customer_pref_delivery_date) values ('2', '2', '2019-08-02', '2019-08-02');
insert into Delivery (delivery_id, customer_id, order_date, customer_pref_delivery_date) values ('3', '1', '2019-08-11', '2019-08-12');
insert into Delivery (delivery_id, customer_id, order_date, customer_pref_delivery_date) values ('4', '3', '2019-08-24', '2019-08-24');
insert into Delivery (delivery_id, customer_id, order_date, customer_pref_delivery_date) values ('5', '3', '2019-08-21', '2019-08-22');
insert into Delivery (delivery_id, customer_id, order_date, customer_pref_delivery_date) values ('6', '2', '2019-08-11', '2019-08-13');
insert into Delivery (delivery_id, customer_id, order_date, customer_pref_delivery_date) values ('7', '4', '2019-08-09', '2019-08-09');
配送表: Delivery
+-----------------------------+---------+
| Column Name | Type |
+-----------------------------+---------+
| delivery_id | int |
| customer_id | int |
| order_date | date |
| customer_pref_delivery_date | date |
+-----------------------------+---------+
delivery_id 是该表中具有唯一值的列。
该表保存着顾客的食物配送信息,顾客在某个日期下了订单,并指定了一个期望的配送日期(和下单日期相同或者在那之后)。
如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。
「首次订单」是顾客最早创建的订单。我们保证一个顾客只会有一个「首次订单」。
编写解决方案以获取即时订单在所有用户的首次订单中的比例。保留两位小数。
结果示例如下所示:
示例 1:
输入:
Delivery 表:
+-------------+-------------+------------+-----------------------------+
| delivery_id | customer_id | order_date | customer_pref_delivery_date |
+-------------+-------------+------------+-----------------------------+
| 1 | 1 | 2019-08-01 | 2019-08-02 |
| 2 | 2 | 2019-08-02 | 2019-08-02 |
| 3 | 1 | 2019-08-11 | 2019-08-12 |
| 4 | 3 | 2019-08-24 | 2019-08-24 |
| 5 | 3 | 2019-08-21 | 2019-08-22 |
| 6 | 2 | 2019-08-11 | 2019-08-13 |
| 7 | 4 | 2019-08-09 | 2019-08-09 |
+-------------+-------------+------------+-----------------------------+
输出:
+----------------------+
| immediate_percentage |
+----------------------+
| 50.00 |
+----------------------+
解释:
1 号顾客的 1 号订单是首次订单,并且是计划订单。
2 号顾客的 2 号订单是首次订单,并且是即时订单。
3 号顾客的 5 号订单是首次订单,并且是计划订单。
4 号顾客的 7 号订单是首次订单,并且是即时订单。
因此,一半顾客的首次订单是即时的。
思路
1.获取客户首次出现的订单 rank()函数排序
2.根据order_date和customer_pref_delivery_date是否相等判断是计划订单还是即时订单
题解
方式一:
select round((sum(immediate)/count(*))*100,2) immediate_percentage
from
(
select if(order_date=customer_pref_delivery_date,1,0)immediate,rank()over(partition by customer_id order by order_date) rk
from Delivery
)t
where rk=1