You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQL连接6个年度用户表并筛选连续参与2年以上的记录?

看来你用LEFT JOIN的思路卡在了非2010年加入的用户身上——这很常见,因为LEFT JOIN是从基准表(比如enyear2010)出发,会漏掉那些从后面年份才开始参与的用户的连续记录。给你一个更可靠的方案,分几步解决:

解决方案思路

核心是先把所有年度的用户数据合并成一张统一的参与清单,再用窗口函数识别连续参与的用户,最后聚合出你需要的字段。

1. 合并所有年度的用户表

先用UNION ALL把6个年度表合并成一张全量的用户参与明细表,这样不管用户是哪一年首次参与,都能被完整纳入:

WITH all_enrollments AS (
    SELECT id, year, other_field1, other_field2 FROM enyear2010
    UNION ALL
    SELECT id, year, other_field1, other_field2 FROM enyear2011
    UNION ALL
    SELECT id, year, other_field1, other_field2 FROM enyear2012
    UNION ALL
    SELECT id, year, other_field1, other_field2 FROM enyear2013
    UNION ALL
    SELECT id, year, other_field1, other_field2 FROM enyear2014
    UNION ALL
    SELECT id, year, other_field1, other_field2 FROM enyear2015
)

注:把other_field1、other_field2替换成你实际需要保留的其他字段,如果字段名在各年度表中不一致,要统一别名。

2. 计算用户的参与统计与连续标记

用窗口函数LAG获取每个用户上一次参与的年份,判断是否和当前年份连续(差值为1);同时计算每个用户的首次参与年份和总参与年数:

, user_enroll_stats AS (
    SELECT 
        id,
        year,
        other_field1,
        other_field2,
        -- 首次参与年份
        MIN(year) OVER (PARTITION BY id) AS startyear,
        -- 总参与年数
        COUNT(DISTINCT year) OVER (PARTITION BY id) AS enrolledyears,
        -- 计算当前年份与上一次参与年份的间隔,1代表连续
        year - LAG(year) OVER (PARTITION BY id ORDER BY year) AS year_gap
    FROM all_enrollments
)

3. 筛选符合条件的用户并生成最终表

我们需要保留至少有一次连续2年参与的用户,同时排除id0000001。根据你对"其他字段"的需求,分两种情况:

情况1:保留用户每年的参与记录(其他字段随年份变化)

SELECT DISTINCT
    id,
    startyear,
    enrolledyears,
    other_field1,
    other_field2
FROM user_enroll_stats
WHERE 
    id != 'id0000001'
    -- 确保用户存在至少一次连续参与的记录
    AND EXISTS (
        SELECT 1 
        FROM user_enroll_stats ues 
        WHERE ues.id = user_enroll_stats.id 
        AND ues.year_gap = 1
    )
ORDER BY id, year;

情况2:聚合到用户级别(其他字段为用户固定属性)

如果其他字段是用户的固定信息(比如注册时的属性),可以取首次参与时的字段值:

SELECT
    id,
    startyear,
    enrolledyears,
    MAX(CASE WHEN year = startyear THEN other_field1 END) AS other_field1,
    MAX(CASE WHEN year = startyear THEN other_field2 END) AS other_field2
FROM user_enroll_stats
WHERE 
    id != 'id0000001'
    AND EXISTS (
        SELECT 1 
        FROM user_enroll_stats ues 
        WHERE ues.id = user_enroll_stats.id 
        AND ues.year_gap = 1
    )
GROUP BY id, startyear, enrolledyears
ORDER BY id;
关键优势
  • 全量合并数据:避免了LEFT JOIN从单一基准表出发的局限性,覆盖所有起始年份的用户
  • 精准识别连续:窗口函数LAG能针对每个用户的参与年份序列,准确判断是否存在连续参与的情况
  • 灵活适配需求:两种输出形式可以匹配你对"其他字段"的不同存储逻辑

内容的提问来源于stack exchange,提问作者N. Reinhart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:47:12