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

Teradata SQL需求:统计指定月份内Prod_cd从A转为B的账户数

解决Teradata中统计A→B单向变更账户的需求

针对你这个统计指定月份内Prod_cd从A单向变更为B的账户需求,我来拆解下实现思路和对应的Teradata SQL代码。核心要抓的就是只有A到B的变更、最终状态为B,且没有反向或来回变更的账户。

假设业务表结构

首先假设你的业务表(比如叫prod_change_log)包含以下核心字段:

  • account_id:唯一账户ID
  • prod_cd:产品代码(A/B)
  • change_date:变更发生的日期

实现思路

  1. 先获取每个账户在指定月份内的所有变更记录,同时拉取该账户在指定月份前的最后一次状态(用来判断初始状态是否为A)
  2. 对每个账户的所有状态记录按时间排序,用窗口函数追踪每一次变更的前后状态
  3. 过滤出符合以下条件的账户:
    • 存在从A到B的变更动作
    • 从未出现过从B到A的反向变更
    • 最终的产品状态是B
    • 初始状态(如果有历史记录)为A,或者当月第一次状态就是A然后变到B

Teradata SQL代码实现

WITH account_change_history AS (
    -- 1. 取指定月份的变更记录 + 每个账户在指定月份前的最后一次状态
    SELECT 
        account_id,
        prod_cd,
        change_date,
        -- 标记是否是指定月份内的记录
        CASE WHEN change_date BETWEEN '2024-03-01' AND '2024-03-31' THEN 1 ELSE 0 END AS is_target_month,
        -- 按账户分组,按日期排序,获取每条记录的前一个状态
        LAG(prod_cd) OVER (PARTITION BY account_id ORDER BY change_date) AS prev_prod_cd
    FROM prod_change_log
    WHERE 
        -- 取指定月份及之前的记录,用来判断初始状态
        change_date <= '2024-03-31'
        -- 如果有必要,可以加其他过滤条件,比如有效账户等
),
account_status_trail AS (
    -- 2. 整理每个账户的状态轨迹,标记关键变更
    SELECT 
        account_id,
        prod_cd,
        prev_prod_cd,
        change_date,
        is_target_month,
        -- 获取每个账户的最后状态
        LAST_VALUE(prod_cd) OVER (PARTITION BY account_id ORDER BY change_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS final_prod_cd,
        -- 标记是否出现过B→A的反向变更
        MAX(CASE WHEN prev_prod_cd = 'B' AND prod_cd = 'A' THEN 1 ELSE 0 END) OVER (PARTITION BY account_id) AS has_reverse_change,
        -- 标记是否出现过A→B的正向变更
        MAX(CASE WHEN prev_prod_cd = 'A' AND prod_cd = 'B' THEN 1 ELSE 0 END) OVER (PARTITION BY account_id) AS has_forward_change
    FROM account_change_history
)
-- 3. 过滤符合条件的账户,去重后统计数量
SELECT COUNT(DISTINCT account_id) AS qualified_account_count
FROM account_status_trail
WHERE 
    -- 有A→B的正向变更
    has_forward_change = 1
    -- 没有B→A的反向变更
    AND has_reverse_change = 0
    -- 最终状态是B
    AND final_prod_cd = 'B'
    -- 初始状态要么是A,要么当月第一次记录就是A(prev_prod_cd为空且prod_cd='A')
    AND (
        (MIN(prev_prod_cd) OVER (PARTITION BY account_id) IS NULL AND MIN(prod_cd) OVER (PARTITION BY account_id) = 'A')
        OR MIN(prev_prod_cd) OVER (PARTITION BY account_id) = 'A'
    )
    -- 确保变更发生在指定月份内(如果初始状态是A,当月变B;或者当月内从A变B)
    AND EXISTS (
        SELECT 1 
        FROM account_change_history ach 
        WHERE ach.account_id = account_status_trail.account_id 
        AND ach.is_target_month = 1 
        AND ach.prev_prod_cd = 'A' 
        AND ach.prod_cd = 'B'
    );

代码说明

  • account_change_history CTE:拉取指定月份及之前的记录,用LAG获取每个状态的前一个值,方便判断变更方向。
  • account_status_trail CTE:标记每个账户的最终状态、是否有反向变更、是否有正向变更,为后续过滤做准备。
  • 最终查询:通过多重条件过滤出符合要求的账户,用COUNT(DISTINCT)得到账户数量。

你可以根据实际的表名、字段名和指定月份(替换代码中的2024-03-01和2024-03-31)调整代码。如果你的表中还有其他需要考虑的逻辑(比如无效变更记录),可以在WHERE条件里补充过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:19:36