【力扣 | SQL题 | 每日3题】力扣1097,1149,1070

embedded/2024/10/22 13:03:33/

1hard + 2 mid,难度还行,当做练手。

1. 力扣1097:游戏玩法分析5

1.1 题目:

表:Activity 

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| player_id    | int     |
| device_id    | int     |
| event_date   | date    |
| games_played | int     |
+--------------+---------+
(player_id,event_date)是此表的主键(具有唯一值的列的组合)
这张表显示了某些游戏的玩家的活动情况
每一行表示一个玩家的记录,在某一天使用某个设备注销之前,登录并玩了很多游戏(可能是 0)

玩家的 安装日期 定义为该玩家的第一个登录日。

我们将日期 x 的 第一天留存率 定义为:假定安装日期为 X 的玩家的数量为 N ,其中在 X 之后的一天重新登录的玩家数量为 MM/N 就是第一天留存率,四舍五入到小数点后两位

编写解决方案,报告所有安装日期、当天安装游戏的玩家数量和玩家的 第一天留存率

以 任意顺序 返回结果表。

结果格式如下所示。

示例 1:

输入:
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            |
+-----------+-----------+------------+--------------+
输出:
+------------+----------+----------------+
| 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

1.2 思路:

看到第一天条件反射就是窗口函数,然后判断是用rank(),dense_rank(), row_number()。

1.3 题解:

-- 第一天=>排名第一=>窗口函数=>row_number
with tep1 as (select player_id , event_date , row_number() over (partition by player_id order by event_date) ranksfrom Activity
), tep2 as (-- 查询到所有第一个登陆日的玩家select *from tep1where ranks = 1
)
-- 然后以日期分组,installs即是该天第一个登陆日的玩家总数
select event_date install_dt, count(*) installs,
round((-- 下面的子查询的意思是:-- 该第一天的下一天且这个玩家在第一天出现过,并且ranks排第二,说明是第二天重新登录的玩家-- where的三个条件才能限定第二天重新登录的数量。-- 然后除以第一天登录的玩家总数,并取两个小数select count(*)from tep1 t2where datediff(t1.event_date, t2.event_date) = -1 and ranks = 2and player_id in (select player_idfrom tep2 t3where datediff(t3.event_date, t2.event_date) = -1 and ranks = 1)) / count(*), 2
) Day1_retention
from tep2 t1
group by event_date
-- 虽然题目并不要求排序,但排序后明显时间缩短,效率提高
-- 因为答案输出给的表是顺序的
order by event_date

2. 力扣1149:文章浏览2

2.1 题目:

表: Views

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| article_id    | int     |
| author_id     | int     |
| viewer_id     | int     |
| view_date     | date    |
+---------------+---------+
此表可能会存在重复行。
此表的每一行都表示某人在某天浏览了某位作者的某篇文章。 
请注意,同一人的 author_id 和 viewer_id 是相同的。

编写解决方案来找出在同一天阅读至少两篇文章的人。

结果按照 id 升序排序。

结果的格式如下。

示例 1:

输入:
Views 表:
+------------+-----------+-----------+------------+
| article_id | author_id | viewer_id | view_date  |
+------------+-----------+-----------+------------+
| 1          | 3         | 5         | 2019-08-01 |
| 3          | 4         | 5         | 2019-08-01 |
| 1          | 3         | 6         | 2019-08-02 |
| 2          | 7         | 7         | 2019-08-01 |
| 2          | 7         | 6         | 2019-08-02 |
| 4          | 7         | 1         | 2019-07-22 |
| 3          | 4         | 4         | 2019-07-21 |
| 3          | 4         | 4         | 2019-07-21 |
+------------+-----------+-----------+------------+
输出:
+------+
| id   |
+------+
| 5    |
| 6    |
+------+

2.2 思路:

注意到为什么要使用两个distinct。

2.3 题解:

-- 先在原表过滤同一天阅读几篇相同的文章的情况,所以要去重
with tep as (select distinct article_id, author_id, viewer_id, view_datefrom Views
)-- 然后根据view_date, viewer_id分组
-- 为什么要去重:打个比方:人物A在19号这天阅读了两篇文章,又在20号这天
-- 阅读了两篇文章,所以会查询到两个相同的记录A,所以要去重。
select distinct viewer_id id
from tep
group by view_date, viewer_id
having count(*) >= 2
order by id

3. 力扣1070:产品销售分析3

3.1 题目:

销售表 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  |
+------------+------------+----------+-------+

3.2 思路:

-- 第一年=> 排名第一 => 窗口函数 => dense_rank

3.3 题解:

-- 第一年=> 排名第一 => 窗口函数 => dense_rank
-- 因为第一年可能有多条记录,所以用dense_rank
with tep as (select product_id , year , quantity, price, dense_rank() over (partition by product_id order by year) ranksfrom Sales
)
select product_id, year first_year, quantity, price
from tep
where ranks = 1


http://www.ppmy.cn/embedded/129563.html

相关文章

线性代数 行列式

一、行列式 1、定义 一个数学概念,主要用于 线性代数中,它是一个可以从方阵(即行数和列数相等的矩阵)形成的一个标量(即一个单一的数值) 2、二阶行列式 ,像这样将一个式子收缩称为一个 2*2 的…

异地多活架构

一、异地多活简介 异地多活是一种高可用性部署策略,旨在通过在地理上分散的多个数据中心部署应用和数据,来提高系统的可用性和灾难恢复能力。这种策略能够确保在一个或多个数据中心发生故障时,系统仍然能够继续提供服务,从而最大…

基于微信小程序的购物系统【附源码、文档】

博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&#x1f3…

什么是 HTML 语义化?

HTML 语义化是指根据内容的结构和含义(内容语义化),选择合适的 HTML 标签(代码语义化),以更好地表达内容的意义和层次。通俗来讲,就是用正确的标签做正确的事情。 优点 1)对机器友好…

基础数据结构——数组(动态数组,二维数组,缓存与局部性原理)

1.概述 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识 因为数组内的元素是连续存储的,所以数组中元素的地址,可以通过其索引计算出来,例如&…

PHP 任务管理:跨行业的科技驱动力量

PHP 任务管理至关重要,它能实现自动化流程,提升工作效率,如自动执行代码测试、订单处理等任务,减少人工操作的繁琐与错误。同时,通过合理的任务调度,确保关键任务优先执行,优化资源分配。在可靠…

网络连接设备的功能与应用概述

目录 一、集线器 二、交换机 三、网桥 四、路由器 五、集线器、交换机、网桥与路由器的比较 备注 一、集线器 定义: 集线器(Hub)是一种物理层设备,它提供多个端口,用于将多个计算机或其他网络设备连接在一起&am…

PetaLinux工程的常用命令——petalinux-config

petalinux-config&#xff1a;使用菜单配置项目或指定组件。 注&#xff1a;有些命令我没用过&#xff0c;瞎翻译有可能会翻译错了。 用法: petalinux-config [options] {--component <COMPONENT> |--get-hw-description[SRC]} 可选参数: -h, --help 显示函数用法…