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

如何筛选指定日期区间内有交易的账户的全部历史记录?

需求与问题说明

现有一张包含Account(账户)、Sale(销售额)、Date(日期)字段的交易表,数据如下:

AccountSaleDate
A$52023-Jan-01
A$82023-Feb-15
B$22023-Mar-03
A$72023-Apr-10
A$92024-Jan-01

当指定日期范围为2023-Apr-01至2023-Apr-30时,期望得到:该日期范围内有交易的账户(比如账户A)的全部历史交易记录,包括区间内及之前的所有记录。

尝试过两种方法但都不符合需求:

  • 直接执行SELECT * FROM 交易表 WHERE Date < '2023-Apr-30',会包含账户B的记录,不符合要求;
  • 用窗口函数MAX(Date) OVER (PARTITION BY Account ORDER BY Date) AS Max_Date后,执行SELECT * WHERE Max_Date < '2023-Apr-30',但账户A的Max_Date是2024-Jan-01,结果为空,也不对。
解决办法

方法1:子查询筛选目标账户

先找出在指定日期范围内有交易的账户,再关联原表获取这些账户的所有历史记录:

SELECT t.*
FROM 交易表 t
INNER JOIN (
    -- 筛选出目标日期范围内有交易的账户
    SELECT DISTINCT Account
    FROM 交易表
    WHERE Date BETWEEN '2023-Apr-01' AND '2023-Apr-30'
) target_accounts ON t.Account = target_accounts.Account
-- 只保留该账户在目标日期及之前的记录
WHERE t.Date <= '2023-Apr-30';

逻辑直观易懂,适配大多数数据库场景。

方法2:窗口函数标记符合条件的账户

换一种窗口函数用法,给每个账户的所有记录打上「是否在目标区间有交易」的标记,再筛选:

WITH account_with_flag AS (
    SELECT 
        *,
        -- 标记该账户是否在目标日期范围内有交易
        MAX(CASE WHEN Date BETWEEN '2023-Apr-01' AND '2023-Apr-30' THEN 1 ELSE 0 END) 
        OVER (PARTITION BY Account) AS has_target_transaction
    FROM 交易表
)
SELECT Account, Sale, Date
FROM account_with_flag
WHERE has_target_transaction = 1 
  AND Date <= '2023-Apr-30';

只要该账户在目标区间有交易,其下所有记录的标记都会是1,后续筛选标记为1且日期不超区间的记录即可。

方法3:EXISTS子查询

用EXISTS判断当前账户是否在目标日期范围内有交易,写法简洁:

SELECT t.*
FROM 交易表 t
WHERE EXISTS (
    SELECT 1
    FROM 交易表 t2
    WHERE t2.Account = t.Account
      AND t2.Date BETWEEN '2023-Apr-01' AND '2023-Apr-30'
)
AND t.Date <= '2023-Apr-30';

数据库优化器通常能高效处理这类关联查询,性能表现较好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:13:17