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

Oracle SQL:基于CLIENT_ID累计唯一值聚合DAYS列的实现方法

实现Oracle SQL中累计唯一客户的每日统计需求

这个需求核心是计算截至每一天的累计唯一CLIENT_ID数量——每个客户仅在首次出现的日期被统计,后续日期再出现时不会重复计入。下面是两种在Oracle中可行的实现方案:

方案一:基于客户首次出现日期的统计

先提取每个客户第一次出现的日期,再统计每一天及之前所有首次出现的客户总数:

WITH first_occurrence AS (
    -- 找出每个CLIENT_ID的首次出现日期
    SELECT CLIENT_ID, MIN(DAY) AS first_day
    FROM DAY_CLIENT
    GROUP BY CLIENT_ID
)
SELECT 
    d.DAY AS DAYS,
    COUNT(f.CLIENT_ID) AS CNT_CLIENT_ID
-- 取出所有不重复的日期,确保每一天都能被统计到
FROM (SELECT DISTINCT DAY FROM DAY_CLIENT) d
-- 关联首次出现记录,统计截止到当前天的所有新客户
LEFT JOIN first_occurrence f ON d.DAY >= f.first_day
GROUP BY d.DAY
ORDER BY d.DAY;

逻辑说明:

  1. 借助CTE first_occurrence 计算每个客户的首次访问日期;
  2. 从原表中提取所有不重复的日期,避免遗漏某天的数据;
  3. 通过左连接将日期与首次出现记录关联,统计每个日期及之前的所有首次出现客户数,得到累计唯一值。

方案二:使用窗口函数标记首次出现并累加

通过窗口函数标记每个客户的首次出现记录,再累加这些标记得到累计值:

SELECT 
    DAY AS DAYS,
    -- 累加从第一天到当前天的首次出现客户数
    SUM(CASE WHEN is_first = 1 THEN 1 ELSE 0 END) OVER (ORDER BY DAY) AS CNT_CLIENT_ID
FROM (
    SELECT 
        DAY,
        CLIENT_ID,
        -- 标记当前记录是否是该客户的首次出现
        CASE WHEN ROW_NUMBER() OVER (PARTITION BY CLIENT_ID ORDER BY DAY) = 1 THEN 1 ELSE 0 END AS is_first
    FROM DAY_CLIENT
) t
GROUP BY DAY
ORDER BY DAY;

逻辑说明:

  1. 内层查询用ROW_NUMBER()给每个客户的出现记录按日期排序,首次出现的记录序号为1,标记为is_first=1;
  2. 外层按天分组后,用SUM() OVER (ORDER BY DAY)累加截止到当前天的所有首次出现标记,得到累计唯一客户数。

两种方案都能得到你期望的结果:

DAYS CNT_CLIENT_ID
1 3
2 3
3 4
4 4

内容的提问来源于stack exchange,提问作者Timothy Quiros

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:22:20