首页 > 数据库 >SQL-聚合函数-550. 游戏玩法分析

SQL-聚合函数-550. 游戏玩法分析

时间:2023-12-01 09:05:14浏览次数:37  
标签:Customers join SQL 玩法 550 player Activity date id

预备知识:

1. date_add函数是一个用于在日期上添加指定时间间隔的函数,它的一般语法如下:

DATE_ADD(date, INTERVAL expression unit)
  • date 是指定的日期。
  • expression 是一个表示要添加的值的表达式。
  • unit 是时间单位,例如 YEARMONTHDAYHOURMINUTESECOND 等。

例如:

SELECT DATE_ADD('2023-01-01', INTERVAL 7 DAY);
SELECT DATE_ADD('2023-01-15', INTERVAL -10 DAY);

解题思路:

题目要求连续两天登录的玩家的占比,那我们可以首先求出用户首次登录的第二天的时间,方法是查询出Activity表中每个用户的第一天时间,并加上1。

select player_id, DATE_ADD(MIN(event_date), INTERVAL 1 DAY) as second_date
from Activity
group by player_id

我们将此表命名为Expected。然后我们要从Activity中查询event_date与Expected.second_date重叠的部分,注意此判定要限定在用户相同的前提下。这部分用户即为在首次登录后第二天也登录了的用户。

select Activity.player_id as player_id
  from (
    select player_id, DATE_ADD(MIN(event_date), INTERVAL 1 DAY) as second_date
    from Activity
    group by player_id
  ) as Expected, Activity
  where Activity.event_date = Expected.second_date and Activity.player_id = Expected.player_id

请注意,此处的“as Expected, Activity”是一个隐式的连接,这种写法实际上等价于用cross join连接两个表。

FROM (SELECT player_id, DATE_ADD(MIN(event_date), INTERVAL 1 DAY) as second_date
      FROM Activity
      GROUP BY player_id) as Expected
JOIN Activity

inner join基于连接条件从两个或者多个表中选择匹配的行,返回在连接条件下存在于两个表中的行,而不包括任何在其他表中没有匹配项的行。当使用“JOIN”关键字但是不指定连接类型时,默认是inner join,连接条件通常使用“ON”来指定。

将此表命名为Result,随后我们只需要得到Result表中的用户数量,以及Activity表中的用户数量,相除保留两位小数。

select IFNULL(round(count(distinct(Result.player_id)) / count(distinct(Activity.player_id)), 2), 0) as fraction

select IFNULL(round(count(distinct(Result.player_id)) / count(distinct(Activity.player_id)), 2), 0) as fraction
from (
  select Activity.player_id as player_id
  from (
    select player_id, DATE_ADD(MIN(event_date), INTERVAL 1 DAY) as second_date
    from Activity
    group by player_id
  ) as Expected, Activity
  where Activity.event_date = Expected.second_date and Activity.player_id = Expected.player_id
) as Result, Activity

Cross join和Inner join:

Cross join:

SELECT 
    Movies.CustomerID, Movies.Movie, Customers.Age, 
    Customers.Gender, Customers.[Education Level], 
    Customers.[Internet Connection], Customers.[Marital Status], 
FROM   
    Customers 
CROSS JOIN 
    Movies

Inner join:

SELECT 
    Movies.CustomerID, Movies.Movie, Customers.Age, 
    Customers.Gender, Customers.[Education Level], 
    Customers.[Internet Connection], Customers.[Marital Status]
FROM   
    Customers 
INNER JOIN 
    Movies ON Customers.CustomerID = Movies.CustomerID

二者的区别是什么呢?

Cross join会产生表格的所有可能组合,例如,100行的table1和100行的table2将产生10000条记录。通俗的讲,下边两者等价:

x CROSS JOIN y
x INNER JOIN y ON 1=1

仅显示两个连接表中具有匹配项的行的连接称为inner join,cross join + where <=> inner join + on:

回到之前的答案,我们可能会疑惑,为什么“count(distinct(Result.player_id)”这里要加distinct呢?答案很简单,因为最后一行执行的是cross join。我们可以更改一下代码让输出结果更直观:

我们可以看到,result的player_id输出了很多次,这是因为cross join做笛卡尔积,使之前result的答案(只有一行“1”)和Activity进行笛卡尔积,结果就为图上所示。因此,必须使用distinct进行去重,否则将会输出错误的结果。牢记,先进行join再select哟!

 

标签:Customers,join,SQL,玩法,550,player,Activity,date,id
From: https://www.cnblogs.com/lbwBH/p/17866546.html

相关文章

  • freesql orm 使用 DynamicFilterInfo 拼接日期查询条件时间格式一个难得的经验
    文本到时间条件的转换前端输入1253-3,后台提示"varchar数据类型到datetime数据类型的转换产生一个超出范围的值"经查询,mssql【datetime】数据类型:最大是9999年12月31日,最小是1753年1月1日所以要拼接限制一下,只是if(val.ToDate()<DateTime.MinValue||val.ToDa......
  • Docker安装mysql配置my.cnf并挂载到外部机器
    1.环境准备,创建外部挂载文件夹conf,data,logmkdir-p/data/dockerdata/mysql3306/{conf,data,log}2.在/data/dockerdata/mysql3306/conf文件夹下创建my.cnf文件my.conf文件配置如下[mysqld]#Mysql服务的唯一编号每个mysql服务Id需唯一server-id=1#服务端口号默认3306......
  • mybatis mysql Data truncation: Incorrect integer value: '' for column 'xxx' at
     com.mysql.jdbc.MysqlDataTruncation:Datatruncation:Incorrectintegervalue:''forcolumn'n_before_group_id'atrow1 mybatisforeach插入时出现这个报错,原因是某字段插入空值时需要插入NULl而不是‘’ 解决办法:<choose><whentest="item.x......
  • window下mysql更换端口号
    我的情况是:本机原来安装了5版本,现在需要用8版本,因此机器同时存在了两个sql版本,一个占用了3306端口,一个占用了3307端口,但是后端默认配置的是3306端口,需要灵活更改版本和端口号。开始吧,安全的更换mysql的端口号,5和8版本都是一样的操作。停止mysql的服务在对应盘符找到Progra......
  • Windows下编译sqlcipher4的shell版本
    越来越多的应用开始接入SQLCipher4了,虽然在Windows上有工具可以打开,但是没法使用脚本解密,也就不能实现自动化。在网上找了很久都没有找到4的编译版本,因此自己找资料编译一下。准备安装openssl,并配置环境变量OPENSSSL_CONFIG,值为C:\ProgramFiles\OpenSSL-Win64\bin\openssl.c......
  • Mysql连接报错解决方案
    错误:Readingfromthestreamhasfailed.解决方案1:添加SslMode=None解决方案2:找到开始菜单下mysql目录下的cmd程序,如图: 1、数据库用户的加密方式里已经是mysql_native_password,但远程链接时依旧提示Authenticationtohost"11.xx.x.xxxforuser’ejdwhwdas’usingmethod......
  • SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解
    SQLSELECTINTO语句SELECTINTO语句将数据从一个表复制到一个新表中。SELECTINTO语法将所有列复制到新表中:SELECT*INTOnewtable[INexternaldb]FROMoldtableWHEREcondition;只复制一些列到新表中:SELECTcolumn1,column2,column3,...INTOnewtable[INexte......
  • MySQL集群搭建,你会吗
    对于目前的应用来说,一般很少使用单机MySQL服务,都会采用主从复制或集群方式,那么如何搭建呢?1.集群1.1概述所谓集群,就是多台服务器之间共享数据,从而实现系统的高可用。节点之间的数据是实时同步的,采用的是同步复制机制。除了有多个主节点外,这些主节点还有多个从节点,当在主节点上进......
  • SQL 数据操作技巧:SELECT INTO、INSERT INTO SELECT 和 CASE 语句详解
    SQLSELECTINTO语句SELECTINTO语句将数据从一个表复制到一个新表中。SELECTINTO语法将所有列复制到新表中:SELECT*INTOnewtable[INexternaldb]FROMoldtableWHEREcondition;只复制一些列到新表中:SELECTcolumn1,column2,column3,...INTOnewtable[INext......
  • 22-基础SQL-多表查询-连接查询(内连接、外连接、自连接)
    多表查询分类  案例:创建部门表和员工表(熟悉多表查询)--部门表CREATETABLEdept(idintauto_incrementcomment"ID"primarykey,namevarchar(50)notnullcomment"部门名称")comment"部门表";--员工表CREATETABLEemp(idintauto_increm......