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

Oracle SQL查询连续下单用户的代码实现求助

问题描述

我是数据库领域新手,最近被一个问题困扰多日:需要找出存在连续多天下单记录的用户(按用户+公司维度,例如20230715、20230716这类连续日期的下单用户),排除无连续下单行为的用户(如仅在20230715、20230719下单的用户)。希望获取对应的Oracle SQL代码,后续还需基于这些用户和日期计算消费金额。

我曾尝试使用ROW_NUMBER()、lag()和lead()函数,但效果有限,以下是我的尝试代码:

WITH ranked_data AS (
    SELECT
        "USER",
        "COMPANY",
        "CREATIONDATE",
        ROW_NUMBER() OVER (PARTITION BY "USER", "COMPANY" ORDER BY "CREATIONDATE") AS rn
    FROM
        P_TEST_P
)
SELECT
    "USER",
    "COMPANY",
    LISTAGG("CREATIONDATE", ', ') WITHIN GROUP (ORDER BY "CREATIONDATE") AS "CONSECUTIVE_DATES"
FROM
    ranked_data
GROUP BY
    "USER",
    "COMPANY";

输入示例数据如下:

USER;Company;creationdate
Liza;Amigurumi KFT;20230712
Liza;Amigurumi KFT;20230713
Liza;Amigurumi KFT;20230714
Liza;Amigurumi KFT;20230715
Liza;Amigurumi KFT;20230728
Liza;Amigurumi KFT;20230718
Liza;Amigurumi KFT;20230722
Liza;Amigurumi KFT;20230723
Liza;Amigurumi KFT;20230724
Liza;Amigurumi KFT;20230729
Liza;Amigurumi KFT;20230729
Liza;Amigurumi KFT;20230729
Liza;Bubu btk;20230703
Liza;Bubu btk;20230703
Liza;Bubu btk;20230708
Liza;Bubu btk;20230711
Liza;Bubu btk;20230722
Liza;PGGNG;20230728
Liza;PGGNG;20230728
Liza;PGGNG;20230728
Liza;PGGNG;20230730
Patrik;YNWA;20230701
Patrik;YNWA;20230706
Patrik;YNWA;20230708
Patrik;YNWA;20230709
Patrik;HUNF;20230725
Patrik;HUNF;20230729
Laszlo;FOUR GRG;20230712
Laszlo;FOUR GRG;20230713
Laszlo;FOUR GRG;20230713
Laszlo;FOUR GRG;20230714
解决方案

核心思路

要找出连续日期的下单记录,关键是先对每个用户+公司的日期去重(同一天多次下单只算一次),然后通过日期减去行号的方式,将连续日期归为同一分组——因为连续日期的行号递增和日期递增同步,差值会保持一致。

步骤1:筛选有连续下单的用户+公司

以下SQL会先标记出所有存在连续下单的用户和公司组合:

WITH distinct_dates AS (
    -- 去重:同一用户+公司同一天的下单只保留一条
    SELECT DISTINCT
        "USER",
        "COMPANY",
        TO_DATE("CREATIONDATE", 'YYYYMMDD') AS order_date  -- 转换为日期类型方便计算
    FROM P_TEST_P
),
date_groups AS (
    -- 对每个用户+公司的日期排序,计算日期与行号的差值,连续日期的差值相同
    SELECT
        "USER",
        "COMPANY",
        order_date,
        order_date - ROW_NUMBER() OVER (PARTITION BY "USER", "COMPANY" ORDER BY order_date) AS group_id
    FROM distinct_dates
),
valid_groups AS (
    -- 筛选出包含至少2个连续日期的分组
    SELECT "USER", "COMPANY"
    FROM date_groups
    GROUP BY "USER", "COMPANY", group_id
    HAVING COUNT(*) >= 2
)
-- 最终得到有连续下单行为的用户+公司
SELECT DISTINCT "USER", "COMPANY"
FROM valid_groups;

步骤2:关联原表计算消费金额

如果需要基于这些用户和日期计算消费金额(假设表中有AMOUNT字段记录单笔消费),可以用以下SQL:

WITH distinct_dates AS (
    SELECT DISTINCT
        "USER",
        "COMPANY",
        TO_DATE("CREATIONDATE", 'YYYYMMDD') AS order_date
    FROM P_TEST_P
),
date_groups AS (
    SELECT
        "USER",
        "COMPANY",
        order_date,
        order_date - ROW_NUMBER() OVER (PARTITION BY "USER", "COMPANY" ORDER BY order_date) AS group_id
    FROM distinct_dates
),
valid_groups AS (
    SELECT "USER", "COMPANY", group_id, order_date
    FROM date_groups
    GROUP BY "USER", "COMPANY", group_id, order_date
    HAVING COUNT(*) OVER (PARTITION BY "USER", "COMPANY", group_id) >= 2
)
-- 计算每个用户+公司在连续日期内的总消费金额
SELECT
    v."USER",
    v."COMPANY",
    LISTAGG(TO_CHAR(v.order_date, 'YYYYMMDD'), ', ') WITHIN GROUP (ORDER BY v.order_date) AS consecutive_dates,
    SUM(p."AMOUNT") AS total_amount
FROM valid_groups v
JOIN P_TEST_P p 
    ON v."USER" = p."USER" 
    AND v."COMPANY" = p."COMPANY"
    AND TO_DATE(p."CREATIONDATE", 'YYYYMMDD') = v.order_date
GROUP BY v."USER", v."COMPANY";

结果说明

  • 针对示例数据,上述代码会筛选出:
    • Liza + Amigurumi KFT(有20230712-20230715、20230722-20230724两组连续日期)
    • Patrik + YNWA(有20230708-20230709一组连续日期)
    • Laszlo + FOUR GRG(有20230712-20230714一组连续日期)
  • 排除掉没有连续下单的组合(如Liza+Bubu btk、Liza+PGGNG、Patrik+HUNF)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:55:55