SQL实战5——统计活跃间隔对用户分级结果

2023-11-15

现有用户行为日志表tb_user_log

问题:统计活跃间隔对用户分级后,各活跃等级用户占比,结果保留两位小数,且按占比降序排序。

  • 用户等级标准简化为:忠实用户(近7天活跃过且非新晋用户)、新晋用户(近7天新增)、沉睡用户(近7天未活跃但更早前活跃过)、流失用户(近30天未活跃但更早前活跃过)。
  • 假设就是数据中所有日期的最大值。
  • 近7天表示包含当天T的近7天,即闭区间[T-6, T]。

问题分解:

  • 计算每个用户最早最晚活跃日期(作为子表t_uid_first_last):

    • 按用户ID分组:GROUP BY uid
    • 统计最早活跃:MIN(DATE(in_time)) as first_dt
    • 统计最晚活跃:MAX(DATE(out_time)) as last_dt
  • 计算当前日期和总用户数(作为子表t_overall_info):

    • 获取当前日期:MAX(DATE(out_time)) as cur_dt
    • 统计总用户数:COUNT(DISTINCT uid) as user_cnt
  • 左连接两表,即将全表统计信息追加到每一行上:t_uid_first_last LEFT JOIN t_overall_info ON 1

  • 计算最早最晚活跃离当前天数差(作为子表t_user_info):

    • 最早活跃距今天数:TIMESTAMPDIFF(DAY,first_dt,cur_dt) as first_dt_diff
    • 最晚(最近)活跃距今天数:TIMESTAMPDIFF(DAY,last_dt,cur_dt) as last_dt_diff
  • 计算每个用户的活跃等级:

    1

    2

    3

    4

    5

    6

    CASE

        WHEN last_dt_diff >= 30 THEN "流失用户"

        WHEN last_dt_diff >= 7 THEN "沉睡用户"

        WHEN first_dt_diff < 7 THEN "新晋用户"

        ELSE "忠实用户"

    END as user_grade

  • 统计每个等级的占比:

    • 按用户等级分组:GROUP BY user_grade

    • 计算占比,总人数从子表得到,非聚合列避免语法错误加了MAX:COUNT(uid) / MAX(user_cnt) as ratio

    • 保留2位小数:ROUND(x, 2)

完整代码:

SELECT user_grade, ROUND(COUNT(uid) / MAX(user_cnt), 2) as ratio
FROM (
    SELECT uid, user_cnt,
        CASE
            WHEN last_dt_diff >= 30 THEN "流失用户"
            WHEN last_dt_diff >= 7 THEN "沉睡用户"
            WHEN first_dt_diff < 7 THEN "新晋用户"
            ELSE "忠实用户"
        END as user_grade
    FROM (
        SELECT uid, user_cnt,
            TIMESTAMPDIFF(DAY,first_dt,cur_dt) as first_dt_diff, 
            TIMESTAMPDIFF(DAY,last_dt,cur_dt) as last_dt_diff
        FROM (
            SELECT uid, MIN(DATE(in_time)) as first_dt,
                MAX(DATE(out_time)) as last_dt
            FROM tb_user_log
            GROUP BY uid
        ) as t_uid_first_last
        LEFT JOIN (
            SELECT MAX(DATE(out_time)) as cur_dt,
                COUNT(DISTINCT uid) as user_cnt
            FROM tb_user_log
        ) as t_overall_info ON 1=1
    ) as t_user_info
) as t_user_grade
GROUP BY user_grade
ORDER BY ratio DESC;

 最后附上原数据表方便大家练习:

DROP TABLE IF EXISTS tb_user_log;
CREATE TABLE tb_user_log (
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    uid INT NOT NULL COMMENT '用户ID',
    artical_id INT NOT NULL COMMENT '视频ID',
    in_time datetime COMMENT '进入时间',
    out_time datetime COMMENT '离开时间',
    sign_in TINYINT DEFAULT 0 COMMENT '是否签到'
) CHARACTER SET utf8 COLLATE utf8_bin;

INSERT INTO tb_user_log(uid, artical_id, in_time, out_time, sign_in) VALUES
  (109, 9001, '2021-08-31 10:00:00', '2021-08-31 10:00:09', 0),
  (109, 9002, '2021-11-04 11:00:55', '2021-11-04 11:00:59', 0),
  (108, 9001, '2021-09-01 10:00:01', '2021-09-01 10:01:50', 0),
  (108, 9001, '2021-11-03 10:00:01', '2021-11-03 10:01:50', 0),
  (104, 9001, '2021-11-02 10:00:28', '2021-11-02 10:00:50', 0),
  (104, 9003, '2021-09-03 11:00:45', '2021-09-03 11:00:55', 0),
  (105, 9003, '2021-11-03 11:00:53', '2021-11-03 11:00:59', 0),
  (102, 9001, '2021-10-30 10:00:00', '2021-10-30 10:00:09', 0),
  (103, 9001, '2021-10-21 10:00:00', '2021-10-21 10:00:09', 0),
  (101, 0, '2021-10-01 10:00:00', '2021-10-01 10:00:42', 1);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL实战5——统计活跃间隔对用户分级结果 的相关文章

  • mysql 详细查询字符串,如通配符

    不知道如何标题我的问题 哈哈 下面是我需要的 我的数据库中的值如下所示 test example 1 test example 2 test example TD 1 这些值的长度可以不同 test example 只是一个示例 某些值将具
  • SQL中如何识别字符串的第一个字符是数字还是字符

    我需要将数据中的第一个字符识别为 SQL Server 中的数字或字符 我对此比较陌生 我不知道从哪里开始 但这是我到目前为止所做的事情 我的数据看起来像这样 TypeDep Transfer From 4Z2 Transfer From
  • 如何检查一个值是否已经存在以避免重复?

    我有一个 URL 表 但我不想要任何重复的 URL 如何使用 PHP MySQL 检查给定 URL 是否已在表中 如果您不想重复 可以执行以下操作 添加唯一性约束 use REPLACE http dev mysql com doc ref
  • 查询嵌套查询结果中两列的位置

    我正在编写这样的查询 select from myTable where X in select X from Y and XX in select X from Y X 列和 XX 列的值必须位于同一查询的结果中 select X fro
  • 如何避免连接两个表时重复

    Student Table SID Name 1 A 2 B 3 C Marks Table id mark subject 1 50 physics 2 40 biology 1 50 chemistry 3 30 mathematics
  • 作为 UDF 结果的列上的 Where 子句

    我有一个用户定义的函数 例如myUDF a b 返回一个整数 我试图确保该函数仅被调用一次 并且其结果可以用作WHERE clause SELECT col1 col2 col3 myUDF col1 col2 AS X From myTa
  • 主键默认可以为NULL吗?为什么这样描述呢?

    我有一张桌子 当我describe这是 mysql gt DESC my table Field Type Null Key Default Extra contact id int 11 NO PRI NULL auto incremen
  • SQL 分隔符上的逗号分隔列

    这是一个 split 函数 它可以应用为dbo Split sf we fs we 当我将字符串更改为列名时 它不起作用 例如dbo Split table columnName Select from dbo Split email pr
  • 如何授予 SQL Server 代理访问权限以便能够写入/修改系统文件?

    我的工作有一个存储过程 运行 BCP 来查询一些数据 如果我单独运行 QUERYOUT 命令 它就会起作用 但是 如果我尝试在作业中运行它 它会创建文件但 挂起 并且数据永远不会放入文件中 这会永远挂起 所以我通常终止 BCP exe 我的
  • 如何为“%abc%”搜索创建文本索引?

    我想对查询进行索引x like abc 如果我有一个如下表 create table t data varchar 100 我想创建一个索引以便能够有效地执行以下操作 select from t where contains abc 和这个
  • 无法访问 Big Query 中类型为 ARRAY> 的字段

    我正在尝试在 BigQuery 上使用标准 SQL 方言 即不是旧版 SQL 运行查询 我的查询是 SELECT date hits referer FROM refresh ga sessions xxxxxx LIMIT 1000 但不
  • 将逗号分隔的主数据替换为列中的描述

    有 2 个 SQL Server 表 Products Name Status Code Product 1 1001 1003 Product 2 1001 1005 1006 Status Code Description 1001 S
  • 从 SQL 数据库获取日期时间

    我的数据库表中有一个 DateTime 记录 我编写一个查询从数据库中获取它 string command2 select Last Modified from Company Data where Company Name Descrip
  • 如何调试参数化 SQL 查询

    我使用 C 连接到数据库 然后使用 Ad hoc SQL 来获取数据 这个简单的 SQL 查询非常方便调试 因为我可以记录 SQL 查询字符串 如果我使用参数化 SQL 查询命令 有没有办法记录 sql 查询字符串以进行调试 我想就是这样的
  • SQL Server 2008 GUID 列全为 0

    我希望这是我做的一个简单的傻事 我的数据库中有一个表 设置如下 column name widget guid data type uniqueidentifier allow nulls false default value newid
  • 如何在postgresql中编写有关最大行数的约束?

    我认为这是一个很常见的问题 我有一张桌子user id INT 和一张桌子photo id BIGINT owner INT 所有者是一个参考user id 我想向表照片添加一个约束 以防止每个用户将超过 10 张照片输入数据库 写这个的最
  • 如何插入包含“&”的字符串

    如何编写包含 字符的插入语句 例如 如果我想将 J J Construction 插入数据库的列中 我不确定这是否有什么不同 但我正在使用 Oracle 9i 我总是忘记这一点 然后又回到它 我认为最好的答案是迄今为止提供的答复的组合 首先
  • 内连接 3 个表

    我正在使用 PHP 和 PDO 我需要重新收集连接 3 个表的信息 photos albums 相册照片 该表具有以下结构 photos photo id int path varchar nick varchar date timesta
  • value >= all(select v2 ...) 产生与 value = (select max(v2) ...) 不同的结果

    Here https stackoverflow com questions 17026651 query from union of joins 17027784 noredirect 1 comment24611997 17027784
  • 在 Oracle 中使用数据透视表的建议

    我需要一份报告 我应该使用数据透视表 报告将按类别分组 使用 case when 语句不好 因为有很多类别 您可以将 Northwind 数据库视为示例 所有类别将显示为列和报告将显示客户在类别中的偏好 我不知道另一个解决方案 并在互联网上

随机推荐

  • 浅谈 one-stage 与 two-stage 目标检测方法

    由于目前实习及找工作的原因 博客更新的频率下降 而在面试过程中也发现 虽然论文是看过了 包括也有输出一些论文笔记 但是很多时候无法形成自己对该领域的一个概括性的认知 无法粗中有细 细中有粗 主要还是基本功不扎实 反应了自己在日常学习中的学习
  • 快速排序(qsort)

    快速排序 排序方法有很多种 选择排序 冒泡排序 归并排序 快速排序等 看名字都知道快速排序是目前公认的一种比较好的排序算法 快速排序的核心思想是二分法 在此 我以升序为例 首先 我们需要选取一个基准数temp 再通过循环比较 将比基准数小的
  • mysql安装版的下载与安装(windows)

    https blog csdn net heting717 article details 73497005 这是安装版 挺方便的
  • soft fork and hard fork

    https bitcoin stackexchange com questions 30817 what is a soft fork https blog csdn net chabuduoxiansheng1 article detai
  • 【OpenAI】《Zotero GPT

    Zotero GPT 如何调教你的GPT 此教程讲述了tag的代码构成 ZoteroGPT中tag的效果就有点像浏览器中的插件 Time Content 0 51 一个tag的基本组成 5 32 tag的工作原理 6 33 删除和新建tag
  • KVM-7、KVM 虚拟机创建的几种方式

    通过对 qemu kvm libvirt 的学习 总结三种创建虚拟机的方式 1 通过 qemu kvm 创建 2 通过 virt install 创建 3 通过 virt manager 创建 在使用这三种创建虚拟机前提是 宿主机必须支持
  • 数据可视化——seaborn(一)

    数据可视化 seaborn 二 简介 seaborn这个库是基于matplotlib并且数据结构与pandas统一的python制图库 seaborn提供了一个高级界面 它是在matplotlib上进行了更高级的API封装 因此使得制图更加
  • Python学习笔记之os.walk()函数

    我们使用os listdir 函数来列出目录下的所有文件和目录放入一个列表进行返回 但是listdir 函数不可对目录的子目录进行扫描 print os listdir 输出 boot dev home proc run sys etc r
  • 前端和后台数据交互总结

    web服务器应用程序 apache tomcat nodeJs Nginx IIS 后台语言 php java net nodeJS 数据库 Mysql SqlServer Oracle 后台mvc ssh ssm 前台mvc js jsp
  • TensorFlow索引与切片语句

    学习课程 1 Basic indexing a tf ones 1 5 5 3 创建tensor a 0 0 结果是5 3的tensor a 0 0 0 结果是1 3的tensor a 0 0 0 1 结果是一个数1 2 Numpy sty
  • python汇总zip文件,压缩包的每个文件格式一样

    汇总zip文件 压缩包的每个文件格式一模一样 from zipfile import ZipFile import pandas as pd import os 打开文件 path r C Users Administrator Deskt
  • gcc/g++ 编译器使用简介

    gcc g 编译器使用简介 原地址 http blogold chinaunix net u3 109487 showart 2153853 html GNU CC 简称gcc 是GNU项目中符合ANSI C标准的编译系统 能够编译用C C
  • WireShark简介和抓包原理及过程

    WireShark 简介 WireShark是一个网络封包分析软件 其功能是记录网络封包 并尽可能显示出最为详细的网络封包信息 WireShark使用WinPCAP作为接口 直接与网卡进行数据报文交换 通俗理解 一个记录网络封包软件 你可以
  • python怎么调用另一个py文件的变量_Python中py文件引用另一个py文件变量的方法

    最近自己初学Python 在编程是遇到一个问题就是 怎样在一个py文件中使用另一个py文件中变量 问题如下 demo1代码 import requests r requests get http www baidu com r encodi
  • 【Linux】常用指令汇总

    目录 1 文件和目录操作 2 进程管理和查询 3 压缩和解压操作 4 系统信息和管理 5 远程和下载操作 6 用户和权限管理 7 时间和日期操作 8 运行和停止程序 9 其他操作 如果这篇文章对你有所帮助 渴望获得你的一个点赞 以下示例涵盖
  • 3S基础知识:VC6.0+MapX编程总结

    一 MapX的帮助 MapX的官方帮助文档是 MapX在线帮助 个人认为 这套文档过于简单 系统性偏差 与ArcEngine的帮助文档不可比 很多MapX的开发技巧在 MapX在线帮助 中查找不到 只能在互联网上搜索 本文试图从一个程序员的
  • 1V转5V芯片,三个元件即可组成完整的稳压方案

    1V低电压要转成5V的电压 需要1V转5V的芯片 由于1V输入 所以不需要指望能输出多大的电流 压差和1V的供电电压意味着供电电流也是无法做大的了 一般1V转5V的输出电流在0MA 100mA 一般60MA应用多 1V转5V电路的BOM物料
  • [LeetCode]202. Happy Number(判断正整数是不是Happy Number)

    202 Happy Number 原题链接 Write an algorithm to determine if a number is happy A happy number is a number defined by the fol
  • java.lang.Integer线程安全吗?

    java lang Integer线程安全 因为 private final int value 不可变
  • SQL实战5——统计活跃间隔对用户分级结果

    现有用户行为日志表tb user log 问题 统计活跃间隔对用户分级后 各活跃等级用户占比 结果保留两位小数 且按占比降序排序 注 用户等级标准简化为 忠实用户 近7天活跃过且非新晋用户 新晋用户 近7天新增 沉睡用户 近7天未活跃但更早