当前位置: 首页 > news >正文

复杂SQL查询案例分析:计算每个月的累积唯一用户数

复杂SQL查询案例分析:计算每个月的累积唯一用户数

题目要求

在这道SQL面试题中,我们需要解决一个关于用户行为数据的查询问题。具体要求如下:

  1. 元数据格式:数据由三列组成,分别是年份(year)、月份(month)和用户ID(userid)。每一行数据代表某个用户在某年某月的行为记录。给出的示例数据如下:

    2020 1 a
    2020 2 a
    2020 2 b
    2020 2 c
    2020 3 a
    2020 3 d
    
  2. 目标:根据上述数据,计算每个月的累积唯一用户数。累积唯一用户数指的是从开始月份到当前月份为止,所有出现过的唯一用户的数量。例如,用户a在2020年1月首次出现,那么从2020年1月开始的所有月份中,都要将用户a计入累积的唯一用户数中。

  3. 期望的输出格式:输出应包含三列,分别是年份(year)、月份(month)、以及累积的唯一用户数。根据给定的元数据,期望的SQL查询结果如下:

    2020 1 1
    2020 2 3
    2020 3 4
    

在这个结果中:

  • 2020年1月有1个唯一用户,即a
  • 2020年2月累积的唯一用户数为3个,分别是abc
  • 2020年3月累积的唯一用户数增加到4个,新增了用户d

建表语句

要执行以上SQL查询,需要首先创建一个数据表并插入给定的数据。建表语句如下:

CREATE TABLE src (year INT,month INT,userid VARCHAR(10)
);INSERT INTO src (year, month, userid) VALUES
(2020, 1, 'a'),
(2020, 2, 'a'),
(2020, 2, 'b'),
(2020, 2, 'c'),
(2020, 3, 'a'),
(2020, 3, 'd');

题目解析

1. 数据结构和需求

给定的数据包含三列:年份(year)、月份(month)和用户ID(userid)。我们需要按月计算累积的唯一用户数量。累积的意思是前几个月出现的所有唯一用户都要包含在当前月的统计中。

2. SQL逻辑分解

为了实现目标查询,SQL分为两个主要部分:

  1. monthly_unique_users CTE (Common Table Expression):
    这个CTE用于生成一个带有行号(rn)的表。ROW_NUMBER函数按照用户ID进行分区(PARTITION BY userid),并根据年份和月份进行排序(ORDER BY year, month)。行号rn = 1表示每个用户第一次出现的记录。

    WITH monthly_unique_users AS (SELECTyear,month,userid,ROW_NUMBER() OVER (PARTITION BY userid ORDER BY year, month) AS rnFROMsrc
    )
    
  2. unique_user_counts CTE:
    这个CTE用于统计每个月的唯一用户数。由于我们只关心每个用户首次出现的月份,所以在计算时我们仅选择rn = 1的记录。然后,通过GROUP BY year, month来统计每个月的唯一用户数量。

    , unique_user_counts AS (SELECTyear,month,COUNT(DISTINCT userid) AS unique_usersFROMmonthly_unique_usersWHERErn = 1GROUP BYyear,month
    )
    
  3. 最终查询:
    最终查询使用窗口函数SUM() OVER来计算累积的唯一用户数量。这个函数按年份和月份排序,并将每个月的唯一用户数加起来。

    SELECTyear,month,SUM(unique_users) OVER (ORDER BY year, month) AS cumulative_unique_users
    FROMunique_user_counts
    ORDER BYyear,month;
    

参考链接

  • SQL ROW_NUMBER() 函数
  • SQL 窗口函数

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • LVS详解
  • 【已解决】AttributeError: ‘diet’ object has no attribute ‘has_key’
  • 前端性能优化方法
  • 快速拷贝复制工具软件@拷贝工具@多线程拷贝@robocopy
  • 视频汇聚平台智能边缘分析一体机分析平台摄像头异常位移算法识别检测
  • 串行通信协议--CAN(Controller Area Network Bus,控制器局域网总线)
  • Python 异步编程:Sqlalchemy 异步实现方式
  • HarmonyOS ArkTS 构建布局
  • Highcharts 条形图:数据可视化的利器
  • 利用python写一个可视化的界面
  • Qt 小功能:加载等待动画——转圈圈
  • 机械行业数字化生产供应链产品解决方案(三)
  • 进程间的通信方式有几种?
  • Handler 消息处理机制总结
  • 【ARM Coresight Trace 系列文章 2.3 -- 简单介绍 ITM 比 Uart 的优点】
  • JS 中的深拷贝与浅拷贝
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • GraphQL学习过程应该是这样的
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Koa2 之文件上传下载
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • quasar-framework cnodejs社区
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • windows下如何用phpstorm同步测试服务器
  • 阿里云应用高可用服务公测发布
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 用Canvas画一棵二叉树
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • ​Python 3 新特性:类型注解
  • ​Redis 实现计数器和限速器的
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #、%和$符号在OGNL表达式中经常出现
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • $.each()与$(selector).each()
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • *2 echo、printf、mkdir命令的应用
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .CSS-hover 的解释
  • .NET Core 中的路径问题
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET Framework .NET Core与 .NET 的区别
  • .NET HttpWebRequest、WebClient、HttpClient
  • .Net MVC4 上传大文件,并保存表单
  • .NET 常见的偏门问题
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .NetCore项目nginx发布
  • .Net接口调试与案例