【leetcode-sql】1082-1084、1097
产品表:Product
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| product_id | int |
| product_name | varchar |
| unit_price | int |
+--------------+---------+
product_id 是这个表的主键.
销售表:Sales
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| seller_id | int |
| product_id | int |
| buyer_id | int |
| sale_date | date |
| quantity | int |
| price | int |
+------ ------+---------+
这个表没有主键,它可以有重复的行.
product_id 是 Product 表的外键.
1082. 销售分析 I
编写一个 SQL 查询,查询总销售额最高的销售者,如果有并列的,就都展示出来。
Product 表:
+------------+--------------+------------+
| product_id | product_name | unit_price |
+------------+--------------+------------+
| 1 | S8 | 1000 |
| 2 | G4 | 800 |
| 3 | iPhone | 1400 |
+------------+--------------+------------+Sales 表:
+-----------+------------+----------+------------+----------+-------+
| seller_id | product_id | buyer_id | sale_date | quantity | price |
+-----------+------------+----------+------------+----------+-------+
| 1 | 1 | 1 | 2019-01-21 | 2 | 2000 |
| 1 | 2 | 2 | 2019-02-17 | 1 | 800 |
| 2 | 2 | 3 | 2019-06-02 | 1 | 800 |
| 3 | 3 | 4 | 2019-05-13 | 2 | 2800 |
+-----------+------------+----------+------------+----------+-------+Result 表:
+-------------+
| seller_id |
+-------------+
| 1 |
| 3 |
+-------------+
Id 为 1 和 3 的销售者,销售总金额都为最高的 2800。
# Write your MySQL query statement below
# 方法1 开窗函数
select seller_id
from
(select seller_id, RANK() over(order by sum(price) DESC) rk
from Sales
group by seller_id) t
where rk=1# 方法2
select seller_id
from Sales
group by seller_id
having sum(price) >= ALL(select sum(price) from Sales group by seller_id)
- 第一种开窗函数,在
group by seller_id
的条件下over()
中不要再使用partition by
,否则变成保留每组第一行数据,总是rk=1; - 第二种使用
ALL运算符
,当前累加和大于等于所有即可。
1083. 销售分析 II
编写一个 SQL 查询,查询购买了 S8 手机却没有购买 iPhone 的买家。注意这里 S8 和 iPhone 是 Product 表中的产品。
Product table:
+------------+--------------+------------+
| product_id | product_name | unit_price |
+------------+--------------+------------+
| 1 | S8 | 1000 |
| 2 | G4 | 800 |
| 3 | iPhone | 1400 |
+------------+--------------+------------+Sales table:
+-----------+------------+----------+------------+----------+-------+
| seller_id | product_id | buyer_id | sale_date | quantity | price |
+-----------+------------+----------+------------+----------+-------+
| 1 | 1 | 1 | 2019-01-21 | 2 | 2000 |
| 1 | 2 | 2 | 2019-02-17 | 1 | 800 |
| 2 | 1 | 3 | 2019-06-02 | 1 | 800 |
| 3 | 3 | 3 | 2019-05-13 | 2 | 2800 |
+-----------+------------+----------+------------+----------+-------+Result table:
+-------------+
| buyer_id |
+-------------+
| 1 |
+-------------+
id 为 1 的买家购买了一部 S8,但是却没有购买 iPhone,而 id 为 3 的买家却同时购买了这 2 部手机。
# Write your MySQL query statement below
# 方法1
select distinct buyer_id
from Sales
where buyer_id not IN(select buyer_idfrom Saleswhere product_id=(select product_id from Productwhere product_name='iPhone'))
AND product_id=(select product_id from Productwhere product_name='S8')# 方法2
select s.buyer_id
from Sales s
JOIN Product p
ON s.product_id=p.product_id
group by buyer_id
having count(IF(product_name='S8', product_name, NULL)) > 0 and
count(IF(product_name='iPhone', product_name, NULL))=0
- 第一种先找到购买过iPhone的
buyer_id
,排除掉这部分用户再查找购买过S8的buyer; - 第二种方法,内连接两张表,
IF(product_name='S8', product_name, NULL)
这样做的原因是,count(字段)
会忽略掉NULL值,所以判断该值是否大于0,第二个count同理。
1084. 销售分析III
编写一个SQL查询,报告2019年春季才售出的产品。即仅在2019-01-01至2019-03-31(含)之间出售的商品。
Product table:
+------------+--------------+------------+
| product_id | product_name | unit_price |
+------------+--------------+------------+
| 1 | S8 | 1000 |
| 2 | G4 | 800 |
| 3 | iPhone | 1400 |
+------------+--------------+------------+Sales table:
+-----------+------------+----------+------------+----------+-------+
| seller_id | product_id | buyer_id | sale_date | quantity | price |
+-----------+------------+----------+------------+----------+-------+
| 1 | 1 | 1 | 2019-01-21 | 2 | 2000 |
| 1 | 2 | 2 | 2019-02-17 | 1 | 800 |
| 2 | 2 | 3 | 2019-06-02 | 1 | 800 |
| 3 | 3 | 4 | 2019-05-13 | 2 | 2800 |
+-----------+------------+----------+------------+----------+-------+Result table:
+-------------+--------------+
| product_id | product_name |
+-------------+--------------+
| 1 | S8 |
+-------------+--------------+
id为1的产品仅在2019年春季销售,其他两个产品在之后销售。
# Write your MySQL query statement below
select s.product_id, product_name
from Sales s
JOIN Product p
ON s.product_id=p.product_id
group by s.product_id
having COUNT(IF(sale_date between '2019-01-01' and '2019-03-31', sale_date, NULL))=count(*)
1097. 游戏玩法分析 V
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| player_id | int |
| device_id | int |
| event_date | date |
| games_played | int |
+--------------+---------+
(player_id,event_date)是此表的主键
这张表显示了某些游戏的玩家的活动情况
每一行表示一个玩家的记录,在某一天使用某个设备注销之前,登录并玩了很多游戏(可能是 0)
玩家的 第一天留存率 定义为:假定安装日期为 X 的玩家的数量为 N ,其中在 X 之后的一天重新登录的玩家数量为 M ,M/N 就是第一天留存率,四舍五入到小数点后两位。
编写一个 SQL 查询,报告所有安装日期、当天安装游戏的玩家数量和玩家的第一天留存率。
Activity 表:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1 | 2 | 2016-03-01 | 5 |
| 1 | 2 | 2016-03-02 | 6 |
| 2 | 3 | 2017-06-25 | 1 |
| 3 | 1 | 2016-03-01 | 0 |
| 3 | 4 | 2016-07-03 | 5 |
+-----------+-----------+------------+--------------+Result 表:
+------------+----------+----------------+
| install_dt | installs | Day1_retention |
+------------+----------+----------------+
| 2016-03-01 | 2 | 0.50 |
| 2017-06-25 | 1 | 0.00 |
+------------+----------+----------------+
玩家 1 和 3 在 2016-03-01 安装了游戏,但只有玩家 1 在 2016-03-02 重新登录,所以 2016-03-01 的第一天留存率是 1/2=0.50
玩家 2 在 2017-06-25 安装了游戏,但在 2017-06-26 没有重新登录,因此 2017-06-25 的第一天留存率为 0/1=0.00
# Write your MySQL query statement below
SELECT t1.install_dt, COUNT(*) AS installs, ROUND(COUNT(next_dt) / COUNT(*), 2) AS Day1_retention
FROM (SELECT t.*, a.event_date AS next_dtFROM (SELECT player_id, MIN(event_date) AS install_dtFROM ActivityGROUP BY player_id) tLEFT JOIN Activity aON t.player_id = a.player_idAND DATE_ADD(t.install_dt, INTERVAL 1 DAY) = a.event_date
) t1
GROUP BY install_dt
查询按
player_id
分组的每个玩家首次登陆日期,作为临时表t:SELECT player_id, MIN(event_date) AS install_dt FROM Activity GROUP BY player_id
表t左连接
Activity
(好处是,表t里player_id没有重复,不会重复计算),DATE_ADD(t.install_dt, INTERVAL 1 DAY) = a.event_date
右表的登陆时间是首次登陆日+1,说明当前用户第二天再次登录;LEFT JOIN
同样是为了最后count
函数计算的时候需要所有用户(不管第二天登陆没有都要算作分母);count(*)
会不会忽略有NULL的行,count(next_dt)
只会统计第二天登陆过的行,保留两位小数即可。
以上是leetcode4道sql题的解答,如有考虑错误或者解法问题,请指正。
【leetcode-sql】1082-1084、1097相关推荐
- 【PL/SQL】匿名块、存储过程、函数、触发器
名词解释 子程序:PL/SQL的过程和函数统称为子程序. 匿名块:以DECLARE或BEGIN开始,每次提交都被编译.匿名块因为没有名称,所以不能在数据库中存储并且不能直接从其他PL/SQL块中调用. ...
- Interview:人工智能大数据岗位面试—【数据分析师】的简介、技能、待遇、进阶的详细攻略
Interview:人工智能&大数据岗位面试-[数据分析师]的简介.技能.待遇.进阶的详细攻略 目录 数据分析师的简介 1.网友经验之谈 数据分析师的待遇 数据分析师的技能 数据分析师进阶 数 ...
- 【LeetCode题解】二叉树的遍历
我准备开始一个新系列[LeetCode题解],用来记录刷题,顺便复习一下数据结构与算法. 1. 二叉树 二叉树(binary tree)是一种极为普遍的数据结构,树的每一个节点最多只有两个节点--左孩 ...
- 【分享贴】学习网站、资源网站、工具网站大杂烩,好用实用,分享给猿友
[分享贴]学习网站.资源网站.工具网站大杂烩,好用实用,分享给猿友 今天还是做一个分享类的文章,不过不只是关于代码类的分享,其中还会涉及到音视频.平面.字体方面的内容,我会尽量对每一类都做介绍,来帮助 ...
- 【代码审计-PHP】审计方法、敏感函数、功能点
前言: 介绍: 博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章). 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员,edus ...
- 【深度学习】对抗扰动、垃圾/钓鱼邮件自动分类和UEBA
[深度学习]对抗扰动.垃圾/钓鱼邮件自动分类和UEBA 文章目录 1 数据集 2 清洗数据集 3 GloVe + LSTM 4 GloVe词向量模型 5 搭建网络整体结构 6 训练模型并验证 7 对抗 ...
- 重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符
题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 示例1 输入: s = &quo ...
- 【LeetCode - 32】最长有效括号
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度. 示例 1: 输入:s = "(()" 输出:2 解释:最长有效括号子串是 " ...
- 【重难点】【Redis 03】缓存雪崩、缓存穿透、缓存击穿、Redis 的内存过期策略、并发读写和双写
[重难点][Redis 03]缓存雪崩.缓存穿透.缓存击穿.Redis 的内存过期策略.并发读写和双写 文章目录 [重难点][Redis 03]缓存雪崩.缓存穿透.缓存击穿.Redis 的内存过期策略 ...
- 【重难点】【JUC 04】synchronized 原理、ReentrantLock 原理、synchronized 和 Lock 的对比、CAS 无锁原理
[重难点][JUC 04]synchronized 原理.ReentrantLock 原理.synchronized 和 Lock 的对比.CAS 无锁原理 文章目录 [重难点][JUC 04]syn ...
最新文章
- java 嵌套对象转xml_Gson对Java嵌套对象和JSON字符串之间的转换 | 学步园
- rails应用ajax之二:使用rails自身支持
- 关于arduino和zigbee串口16进制通信问题
- unix下网络编程之I/O复用(二)
- 构建根文件系统之busybox(四)完善
- 专家解读 | 数据中心,从“电老虎”走向“数字经济发动机”
- linux mysql清除缓存_案例:通过shell脚本实现mysql数据备份与清理
- .Net PetShop 4.0的缓存处理
- 01-06 Linux常用命令-统计
- unity 后台计时器实现
- 无废话ExtJs 入门教程八[脚本调试Firefox:firebug]
- tomcat自动启动 linux,Linux设置tomcat开机自启动
- kubernetes kubeadm init kube-apiserver.yaml already exists
- spring cloud config-server 高可用配置中心
- 【bat批处理】常用bat批处理内部命令简介
- SI5341驱动(verilog)
- 光纤收发器的原理及应用_光纤收发器
- 最新邮箱密码破解方法
- 版本号(SNAPSHOT GA....)都是啥意思
- Search()函数使用方法