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

Oracle SQL筛选:仅保留全年各月均有记录的账户

解决方法:筛选有12个月账单历史的账户

针对你的需求,分两种常见场景给出具体实现,同时纠正你之前思路的问题:

一、筛选有至少12个不同月份账单的账户(非连续也可)

你之前用HAVING COUNT(date) = 12效果不对,大概率是因为同一个账户在某个月有多条账单记录,COUNT(date)会把这些重复记录都算进去,导致统计的是账单条数而非月份数。正确的做法是统计去重后的月份数量:

方法1:先分组统计再关联原表

WITH account_month_stats AS (
    SELECT 
        account_id,
        -- 把日期截断到月份,确保同一个月的记录只算一次
        COUNT(DISTINCT DATE_TRUNC('month', bill_date)) AS total_bill_months
    FROM 
        monthly_bills
    GROUP BY 
        account_id
)
-- 关联原表获取符合条件的所有账单记录
SELECT mb.*
FROM monthly_bills mb
JOIN account_month_stats ams ON mb.account_id = ams.account_id
WHERE ams.total_bill_months >= 12;

方法2:直接用HAVING筛选账户

如果只需要获取符合条件的账户ID,不需要完整账单记录,可以简化:

SELECT 
    account_id,
    COUNT(DISTINCT DATE_TRUNC('month', bill_date)) AS total_bill_months
FROM 
    monthly_bills
GROUP BY 
    account_id
HAVING 
    COUNT(DISTINCT DATE_TRUNC('month', bill_date)) >= 12;

二、筛选有连续12个月账单记录的账户

如果你的需求是账户必须有连续12个月的账单(比如最近连续12个月,或任意连续12个月),可以用ROW_NUMBER()配合分组筛选,这里关键是要给每个账户单独排序(你之前的问题就是没加PARTITION BY account_id,导致全局排序):

WITH unique_monthly_bills AS (
    -- 先去重同一个账户同一个月的重复账单
    SELECT DISTINCT
        account_id,
        DATE_TRUNC('month', bill_date) AS bill_month
    FROM 
        monthly_bills
),
ordered_months AS (
    SELECT 
        account_id,
        bill_month,
        -- 按账户分组,对账单月份从小到大排序
        ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY bill_month) AS rn
    FROM 
        unique_monthly_bills
),
continuous_groups AS (
    SELECT 
        account_id,
        bill_month,
        -- 连续的月份会生成相同的group_key
        bill_month - INTERVAL '1 month' * rn AS group_key
    FROM 
        ordered_months
)
-- 找出每个连续组中月份数>=12的账户
SELECT DISTINCT account_id
FROM continuous_groups
GROUP BY account_id, group_key
HAVING COUNT(*) >= 12;

解释:通过PARTITION BY account_id让ROW_NUMBER()按每个账户单独排序,然后用月份减去排序号乘以1个月,连续的月份会得到相同的group_key,最后统计每个group_key下的月份数,就能找出有连续12个月账单的账户。

对你之前思路的纠正

  • ROW_NUMBER()的问题:必须加上PARTITION BY account_id,才能让排序在每个账户内部进行,而不是全局排序。
  • COUNT(date)的问题:要统计月份数而非账单条数,必须用COUNT(DISTINCT 月份字段),避免同一个月的多条账单干扰统计结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:55:38