首页 > 数据库 >SQL进阶实战技巧:用户会话内行为模式挖掘

SQL进阶实战技巧:用户会话内行为模式挖掘

时间:2025-01-21 13:28:36浏览次数:3  
标签:group 进阶 timestamp 会话 session user behavior SQL id

目录

0 问题描述

 1 数据准备

2 问题分析

3 小结 

往期精彩


0 问题描述

分析用户在每个会话内的行为序列,找出最常见的前 N 种行为模式,并按用户分群。

用户表结构和数据

假设有名为user_behavior_log的用户行为日志表,包含以下字段:

字段名数据类型描述
user_idINT用户 ID
behaviorSTRING用户行为,例如viewclickpurchase
timestampBIGINT行为发生的时间戳
user_groupSTRING用户分组,例如group_agroup_b

 示例数据,例如:

user_idbehaviortimestampuser_group
1view1678886400group_a
1click1678886460group_a
2view1678886520group_b
1purchase1678886580group_a
2view1678886640group_b
2click1678886700group_b
3view1678886760group_a
3click1678886820group_a
3view1678886880group_a
1view1678887000group_a
1click1678887060group_a

SQL 结果输出

user_grouppatternfrequency
group_aview->click->view1
group_aview->click->purchase1
group_bview->view->click1

 

 1 数据准备

CREATE TABLE user_behavior_log (
    user_id INT,
    behavior STRING,
    timestamp BIGINT,
    user_group STRING
);
INSERT INTO TABLE user_behavior_log
SELECT *
FROM (
    SELECT stack(11,
        1, 'view', 1678886400, 'group_a',
        1, 'click', 1678886460, 'group_a',
        2, 'view', 1678886520, 'group_b',
        1, 'purchase', 1678886580, 'group_a',
        2, 'view', 1678886640, 'group_b',
        2, 'click', 1678886700, 'group_b',
        3, 'view', 1678886760, 'group_a',
        3, 'click', 1678886820, 'group_a',
        3, 'view', 1678886880, 'group_a',
        1, 'view', 1678887000, 'group_a',
        1, 'click', 1678887060, 'group_a'
    ) AS (user_id, behavior, timestamp, user_group)
) subquery;

----------------------------

create TABLE user_behavior_log as
    (SELECT stack(11,
                  1, 'view', 1678886400, 'group_a',
                  1, 'click', 1678886460, 'group_a',
                  2, 'view', 1678886520, 'group_b',
                  1, 'purchase', 1678886580, 'group_a',
                  2, 'view', 1678886640, 'group_b',
                  2, 'click', 1678886700, 'group_b',
                  3, 'view', 1678886760, 'group_a',
                  3, 'click', 1678886820, 'group_a',
                  3, 'view', 1678886880, 'group_a',
                  1, 'view', 1678887000, 'group_a',
                  1, 'click', 1678887060, 'group_a'
            ) AS (user_id, behavior, `timestamp`, user_group));

2 问题分析

求解步骤

  1. 会话划分:根据用户 ID 和时间戳,将会话划分出来。
  2. 构建会话内行为序列:按照会话 ID、用户ID、USER_GROUP进行分组,并将会话的行为连接成一个序列。
  3. 定义行为模式:根据业务规则,进行用户行为模式匹配。
  4. 统计模式频次:统计不同行为模式的出现次数。
  5. 按用户分群:按用户分群,并分别统计每个用户群体的最常见行为模式。

会话划分:根据用户 ID 和时间戳,将会话划分出来。

WITH user_sessions AS (select user_id,
                              behavior,
                              `timestamp`,
                              user_group,
                              sum(diff) over (partition by user_id order by `timestamp`) session_id
                       from (SELECT user_id,
                                    behavior,
                                    `timestamp`,
                                    user_group,
                                    CASE
                                        WHEN (`timestamp` - LAG(`timestamp`, 1, 0)
                                                                OVER (PARTITION BY user_id ORDER BY `timestamp`)) >
                                             1800 THEN 1
                                        ELSE 0 END diff
                             FROM user_behavior_log) t
                             )
select *
from user_sessions;

 构建会话内行为序列:按照会话 ID、用户ID、USER_GROUP进行分组,并将会话的行为连接成一个序列。

WITH user_sessions AS (select user_id,
                              behavior,
                              `timestamp`,
                              user_group,
                              sum(diff) over (partition by user_id order by `timestamp`) session_id
                       from (SELECT user_id,
                                    behavior,
                                    `timestamp`,
                                    user_group,
                                    CASE
                                        WHEN (`timestamp` - LAG(`timestamp`, 1, 0)
                                                                OVER (PARTITION BY user_id ORDER BY `timestamp`)) >
                                             1800 THEN 1
                                        ELSE 0 END diff
                             FROM user_behavior_log) t
                             )
,

session_behavior_sequences AS (
    SELECT
        user_id,
        session_id,
        user_group,
        collect_list(behavior) AS behavior_sequence
    FROM
        user_sessions
    GROUP BY
        user_id,
        session_id,
        user_group
)
     select *
from session_behavior_sequences;

定义行为模式:根据业务规则,进行用户行为模式匹配。 

WITH user_sessions AS (select user_id,
                              behavior,
                              `timestamp`,
                              user_group,
                              sum(diff) over (partition by user_id order by `timestamp`) session_id
                       from (SELECT user_id,
                                    behavior,
                                    `timestamp`,
                                    user_group,
                                    CASE
                                        WHEN (`timestamp` - LAG(`timestamp`, 1, 0)
                                                                OVER (PARTITION BY user_id ORDER BY `timestamp`)) >
                                             1800 THEN 1
                                        ELSE 0 END diff
                             FROM user_behavior_log) t
                             )
,

session_behavior_sequences AS (
    SELECT
        user_id,
        session_id,
        user_group,
        collect_list(behavior) AS behavior_sequence
    FROM
        user_sessions
    GROUP BY
        user_id,
        session_id,
        user_group
)
,

session_behavior_patterns AS (
    SELECT
        user_id,
        session_id,
        user_group,
        -- 将数组转换为字符串
        regexp_replace(concat_ws(',', behavior_sequence), '^([^,]+,[^,]+,[^,]+).*', '$1') AS pattern_str,
        size(behavior_sequence) AS seq_length
    FROM
        session_behavior_sequences
)

select *
from session_behavior_patterns;

 

  • session_behavior_patterns子查询
    • 首先使用concat_ws(',', behavior_sequence)将数组转换为以逗号分隔的字符串。
    • 然后使用regexp_replace函数,通过正则表达式^([^,]+,[^,]+,[^,]+).*匹配字符串开头的前三个逗号分隔的部分,并将其替换为匹配到的内容,即模拟了对数组前三个元素的截取,得到pattern_str。同时计算数组的长度seq_length

统计模式频次:统计不同行为模式的出现次数 

 

WITH user_sessions AS (select user_id,
                              behavior,
                              `timestamp`,
                              user_group,
                              sum(diff) over (partition by user_id order by `timestamp`) session_id
                       from (SELECT user_id,
                                    behavior,
                                    `timestamp`,
                                    user_group,
                                    CASE
                                        WHEN (`timestamp` - LAG(`timestamp`, 1, 0)
                                                                OVER (PARTITION BY user_id ORDER BY `timestamp`)) >
                                             1800 THEN 1
                                        ELSE 0 END diff
                             FROM user_behavior_log) t
                             )
,

session_behavior_sequences AS (
    SELECT
        user_id,
        session_id,
        user_group,
        collect_list(behavior) AS behavior_sequence
    FROM
        user_sessions
    GROUP BY
        user_id,
        session_id,
        user_group
)
,

session_behavior_patterns AS (
    SELECT
        user_id,
        session_id,
        user_group,
        -- 将数组转换为字符串
        regexp_replace(concat_ws(',', behavior_sequence), '^([^,]+,[^,]+,[^,]+).*', '$1') AS pattern_str,
        size(behavior_sequence) AS seq_length
    FROM
        session_behavior_sequences
)

,

pattern_frequencies AS (
    SELECT
        user_group,
        -- 将字符串转换回类似模式的格式
        replace(pattern_str, ',', '->') AS pattern,
        count(*) AS frequency
    FROM
        session_behavior_patterns
    WHERE
        seq_length >= 3
    GROUP BY
        user_group,
        pattern_str
)
    select * from pattern_frequencies;

 

按用户分群:按用户分群,并分别统计每个用户群体的最常见行为模式。 

 

WITH user_sessions AS (select user_id,
                              behavior,
                              `timestamp`,
                              user_group,
                              sum(diff) over (partition by user_id order by `timestamp`) session_id
                       from (SELECT user_id,
                                    behavior,
                                    `timestamp`,
                                    user_group,
                                    CASE
                                        WHEN (`timestamp` - LAG(`timestamp`, 1, 0)
                                                                OVER (PARTITION BY user_id ORDER BY `timestamp`)) >
                                             1800 THEN 1
                                        ELSE 0 END diff
                             FROM user_behavior_log) t
                             )
,

session_behavior_sequences AS (
    SELECT
        user_id,
        session_id,
        user_group,
        collect_list(behavior) AS behavior_sequence
    FROM
        user_sessions
    GROUP BY
        user_id,
        session_id,
        user_group
)
,

session_behavior_patterns AS (
    SELECT
        user_id,
        session_id,
        user_group,
        -- 将数组转换为字符串
        regexp_replace(concat_ws(',', behavior_sequence), '^([^,]+,[^,]+,[^,]+).*', '$1') AS pattern_str,
        size(behavior_sequence) AS seq_length
    FROM
        session_behavior_sequences
)

,

pattern_frequencies AS (
    SELECT
        user_group,
        -- 将字符串转换回类似模式的格式
        replace(pattern_str, ',', '->') AS pattern,
        count(*) AS frequency
    FROM
        session_behavior_patterns
    WHERE
        seq_length >= 3
    GROUP BY
        user_group,
        pattern_str
)
    ,
ranked_patterns AS (
    SELECT
        user_group,
        pattern,
        frequency,
        row_number() OVER (PARTITION BY user_group ORDER BY frequency DESC) AS rn
    FROM
        pattern_frequencies
)
SELECT
    user_group,
    pattern,
    frequency
FROM
    ranked_patterns
WHERE
    rn <= 2;

3 小结 

本文核心技巧总结

 regexp_replace(concat_ws(',', behavior_sequence), '^([^,]+,[^,]+,[^,]+).*', '$1') AS pattern_str

整体函数作用

regexp_replace 是 Hive 中的函数,用于基于正则表达式进行字符串替换。它的语法是 regexp_replace(string A, string B, string C),表示在字符串 A 中,将匹配正则表达式 B 的部分替换为字符串 C

正则表达式部分

  • ^([^,]+,[^,]+,[^,]+).*
    • ^:表示匹配字符串的开始位置。这确保我们从字符串的开头进行匹配。
    • ([^,]+,[^,]+,[^,]+):这是一个捕获组。
      • [^,]+:表示匹配除逗号 , 以外的一个或多个字符。在这里,它用于匹配数组中的每个元素(因为我们之前用逗号将数组元素连接成了字符串)。
      • 整个捕获组 ([^,]+,[^,]+,[^,]+) 表示匹配以逗号分隔的前三个元素,即模拟获取数组的前三个元素。
    • .*:表示匹配零个或多个任意字符,直到字符串的末尾。这部分用于匹配捕获组之后的所有剩余字符,以便在替换时将其丢弃。
  • 替换部分

    • $1:在 regexp_replace 函数中,$1 表示对第一个捕获组的反向引用。也就是说,我们将整个匹配到的字符串(从开头到剩余部分)替换为捕获组 ([^,]+,[^,]+,[^,]+) 所匹配到的内容,即行为序列字符串的前三个以逗号分隔的元素。

实际效果

  • 假设 behavior_sequence 数组被 concat_ws(',', behavior_sequence) 拼接成字符串 "view,click,purchase,add_to_cart",经过 regexp_replace 函数处理后,将得到 "view,click,purchase",这就模拟了从数组中提取前三个元素的操作。

通过这种方式,即使 Hive 中没有 array_slice 函数,也能通过字符串操作和正则表达式来获取行为序列中的特定部分,作为行为模式提取的一部分。

往期精彩

SQL进阶技巧:如何分析双重职务问题?

其实数据分析,只是在筛选没有准备的人,写给正在求职的你们。。。

SQL进阶技巧:如何求解直接线上最多的点数?

数据科学与SQL:如何利用本福特法则识别财务数据造假?

SQL进阶技巧:如何查找相邻座位员?| 员工座位安排问题

SQL进阶技巧:如何根据座位距离查找员工?| 员工座位安排问题

~~SQL进阶实战技巧系列~~ 

SQL很简单,可你却写不好?每天一点点,收获不止一点点_sql断点-CSDN博客文章浏览阅读1.3k次,点赞54次,收藏19次。在写本文之前,我需要跟大家探讨以下几个话题。SQL进阶技巧:车辆班次问题分析SQL 进阶技巧:断点重分组应用求连续段的最后一个数及每段的个数【拼多多面试题】SQL进阶技巧-:字符串时间序列分析法应用之用户连续签到天数及历史最大连续签到天数问题【腾讯面试题】SQL进阶技巧:断点重分组算法应用之用户订单日期间隔异常问题分析SQL进阶技巧:如何对连续多条记录进行合并?【GroingIO 面试题】SQL进阶技巧:断点重分组算法应用之相邻时间间隔跳变问题分析。_sql断点https://flyingsql.blog.csdn.net/article/details/143609283 

标签:group,进阶,timestamp,会话,session,user,behavior,SQL,id
From: https://blog.csdn.net/godlovedaniel/article/details/145141340

相关文章

  • Mysql并发控制和日志
    MySQL是一个广泛使用的关系数据库管理系统,在高并发环境中,如何有效地控制并发和管理日志至关重要。本文将详细介绍MySQL的并发控制机制和日志管理策略,以帮助开发人员和数据库管理员更好地理解和优化数据库性能。一、并发控制并发控制是指在多用户环境下管理对数据库的并发访问......
  • SQL查询最近的年、月、周、日的统计数据
    <selectid="statTraffic"resultType="com.nuorui.module.platform.domain.vo.StatTotalVO"><![CDATA[SELECTCASEWHEN#{dateType}=0THENYEAR(date_series.generated_date)--......
  • sqlite3 mysql每秒查询性能
     数据库的查询性能(如每秒查询次数,QPS,即QueriesPerSecond)取决于多种因素,包括数据库引擎、硬件配置、查询复杂度、数据量以及系统优化程度等。以下是对SQLite和MySQL每秒查询能力的比较和分析:SQLite每秒查询能力性能特点:SQLite是一个轻量级、文件系统级的数......
  • 通过sqlserver添加修改系统管理员账号.120510
    一,思路:在其他服务器B,通过sa账号远程登录需增加/修改系统管理员账号的服务器A,用sqlserver的xp_cmdshell功能,模拟cmd通过netuser命令进行添加或者修改系统管理员账号。特别提示:此解决方案只适用于服务器没有加域且忘记管理员密码的用户使用,请不要作为非法用途!二,解决方法:0,在服务......
  • MySQL架构总览_查询执行流程_SQL解析顺序
    目录MySQL架构总览查询执行流程连接处理结果SQL解析顺序准备工作FROMWHEREGROUPBYHAVINGSELECTORDERBYLIMIT总结参考书籍MySQL架构总览架构最好看图,再配上必要的说明文字。下图根据参考书籍中一图为原本,再在其上添加上了自己的理解。从上图中我们可以看到,整个架构分为两......
  • SQL Server 2005部署备份任务.120308
    环境:SQLServer2005任务:1,每日凌晨1点给本地sqlserver做本地完整备份,且只保留7天的本地备份;2,每日凌晨5点将本地的备份打包上传到存储服务器。思路:1,sqlserver2005不支持SQLServer2000的sqlmaint命令,所以,需要通过数据库维护计划进行备份,而不能一步成型的写bat脚本;2,备份地址......
  • SQLServer2005恢复Master库.110509
    master库对于SQLServer来说,是很重要的系统数据库,保存着所有Sqlserver的用户信息、数据库信息等,当数据库崩溃时,master数据库的恢复成功与否起着重要的作用。这就跟Oracle的System表空间一样,非常的重要。备份数据前期准备:(1)在备用机准备好和生产机器一样的sql2005数据库环境(注意数......
  • MySQL数据库开启远程访问权限
    1、背景描述默认情况下,MySQL只允许本地登录,即只能在安装MySQL数据库所在的主机环境中访问。在实际开发和使用中,一般需要访问远程服务器的数据库,此时就需要开启服务器端MySQL的远程访问权限。2、查看MySQL的用户表如上图所示,Host列指定了允许用户登录所使用的IP,比如u......
  • PL/SQL 删除外键 ORA-02443: 无法删除约束条件-不存在的约束条件
    在PL/SQL中删除外键,无论是在【对象】窗口可视化操作删除还是用drop语句都会报错:ORA-02443:无法删除约束条件-不存在的约束条件看到有人有同样的问题。亲测之后:情况一:常规操作ALTERTABLEtable_nameDROPCONSTRAINTforeignkeyname;情况二:需要加引号(而且是双引号)ALTERTABL......
  • MySQL 中单独获取已知日期的年月日
    在MySQL中,处理日期和时间是一项常见任务。通常,我们需要从已知的日期中提取年、月、日等部分信息。MySQL提供了一些内置函数,可以方便地进行这些操作。本文将详细介绍如何在MySQL中单独获取已知日期的年、月、日部分。一、提取年份(Year)要从日期中提取年份,可以使用 YEAR() 函数......