下面是我try 列出连续购买10天或以上的客户.

我正在try 获取输出(见下文),需要一些帮助.我知道这可能可以用Match_Recognition来完成,但我不太熟悉它,所以我更愿意提高我当前的try 或确定性,并接受任何其他可以实现我想要的输出的建议.

下面是我的测试用例.提前感谢所有回复的人.


ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';

CREATE TABLE customers 
(CUSTOMER_ID, FIRST_NAME, LAST_NAME) AS
SELECT 1, 'Faith', 'Mazzarone' FROM DUAL UNION ALL
SELECT 2, 'Lisa', 'Saladino' FROM DUAL UNION ALL
SELECT 3, 'Micheal', 'Palmice' FROM DUAL UNION ALL
SELECT 4, 'Joseph', 'Zaza' FROM DUAL UNION ALL
SELECT 5, 'Jerry', 'Torchiano' FROM DUAL;

ALTER TABLE customers 
ADD CONSTRAINT customers_pk PRIMARY KEY (customer_id);

CREATE TABLE items 
(PRODUCT_ID, PRODUCT_NAME, PRICE) AS
SELECT 100, 'Black Shoes', 79.99 FROM DUAL UNION ALL
SELECT 101, 'Brown Pants', 111.99 FROM DUAL UNION ALL
SELECT 102, 'White Shirt', 10.99 FROM DUAL;

ALTER TABLE items 
ADD CONSTRAINT items_pk PRIMARY KEY (product_id);

create table purchases(
  ORDER_ID NUMBER GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
  customer_id   number, 
  PRODUCT_ID NUMBER, 
  QUANTITY NUMBER, 
  purchase_date timestamp
);

ALTER TABLE purchases 
ADD CONSTRAINT order_pk PRIMARY KEY (order_id);

ALTER TABLE purchases ADD CONSTRAINT customers_fk FOREIGN KEY (customer_id) REFERENCES customers(customer_id);

ALTER TABLE purchases ADD CONSTRAINT items_fk FOREIGN KEY (PRODUCT_ID) REFERENCES items(product_id);

insert  into purchases (customer_id, product_id, quantity, purchase_date) 
SELECT 3, 102, 4,TIMESTAMP '2022-12-22 21:44:35' + NUMTODSINTERVAL ( LEVEL * 2, 'DAY') FROM    dual
CONNECT BY  LEVEL <= 15 UNION ALL 
select 1, 101,3, date '2023-03-29' + level * interval '2' day from dual
          connect by level <= 12
union all
select 2, 101,2, date '2023-01-15' + level * interval '8' hour from dual
          connect by level <= 15
union all
select 2, 102,2,date '2023-04-13' + level * interval '1 1' day to hour from dual
          connect by level <= 11
union all
select 3, 101,2, date '2023-02-01' + level * interval '1 05:03' day to minute from dual
          connect by level <= 10
union all
select 3, 101,1, date '2023-04-22' + level * interval '23' hour from dual
          connect by level <= 23
union all
select 3, 100,1,  date '2022-03-01' + level * interval '1 00:23:05' day to second from dual
          connect by level <= 15
union all
select 4, 102,1, date '2023-01-01' + level * interval '5' hour from dual
          connect by level <= 60;

WITH t as (
     select distinct CUSTOMER_ID,
    trunc(PURCHASE_DATE) dat
       from purchases
    )
    ,tt as (
        select t.*
        ,row_number() over (partition by CUSTOMER_ID order by dat) rn
        from t
    )
   ,ttt as (
   select CUSTOMER_ID, 
         min(dat) start_date,
         max(dat) end_date,
         count(*) day_count
     from tt
     group by 
      CUSTOMER_ID, dat-rn
      having count(*) >= 10
   )
   select 
           c.customer_id,
           c.first_name,
           c.last_name,  
           ttt.start_date,
           ttt.end_date,
           ttt.day_count
     from   customers c, ttt
    where  
    c.customer_id = ttt.customer_id;

/*desired output */

CUSTOMER_ID FIRST_NAME  LAST_NAME   FIRST_DATE  LAST_DATE   DAY_COUNT   PURCHASE_COUNT
2   Lisa    Saladino    14-APR-2023 00:00:00    24-APR-2023 00:00:00    11  11
3   Micheal Palmice 02-MAR-2022 00:00:00    16-MAR-2022 00:00:00    15  15
3   Micheal Palmice 22-APR-2023 00:00:00    14-MAY-2023 00:00:00    23  23
4   Joseph  Zaza    01-JAN-2023 00:00:00    13-JAN-2023 00:00:00    13  60

推荐答案

我更愿意加强我现在的try

您可以通过更改第一个CTE‘t’查询来获得想要的结果:

     select distinct CUSTOMER_ID,
    trunc(PURCHASE_DATE) dat
       from purchases

     select CUSTOMER_ID,
    trunc(PURCHASE_DATE) dat,
    count(*) cnt
       from purchases
   group by CUSTOMER_ID, trunc(PURCHASE_DATE)

然后将其包含在‘TTT’查询中:

         sum(cnt) purchase_count

and final select list. Al至gether (and without fixing indentation or switching 至 modern join syntax):

WITH t as (
     select CUSTOMER_ID,
    trunc(PURCHASE_DATE) dat,
    count(*) cnt
       from purchases
   group by CUSTOMER_ID, trunc(PURCHASE_DATE)
    )
    ,tt as (
        select t.*
        ,row_number() over (partition by CUSTOMER_ID order by dat) rn
        from t
    )
   ,ttt as (
   select CUSTOMER_ID, 
         min(dat) start_date,
         max(dat) end_date,
         count(*) day_count,
         sum(cnt) purchase_count
     from tt
     group by 
      CUSTOMER_ID, dat-rn
      having count(*) >= 10
   )
   select 
           c.cus至mer_id,
           c.first_name,
           c.last_name,  
           ttt.start_date,
           ttt.end_date,
           ttt.day_count,
           ttt.purchase_count
     from   cus至mers c, ttt
    where  
    c.cus至mer_id = ttt.cus至mer_id;
CUSTOMER_ID FIRST_NAME LAST_NAME START_DATE END_DATE DAY_COUNT PURCHASE_COUNT
2 Lisa Saladino 14-APR-2023 00:00:00 24-APR-2023 00:00:00 11 11
3 Micheal Palmice 02-MAR-2022 00:00:00 16-MAR-2022 00:00:00 15 15
3 Micheal Palmice 22-APR-2023 00:00:00 14-MAY-2023 00:00:00 23 23
4 Joseph Zaza 01-JAN-2023 00:00:00 13-JAN-2023 00:00:00 13 60

fiddle

不过,我建议使用更简单的方法,如@astentx或@MTO的答案所示.

Sql相关问答推荐

具有2个共享列的两个表的Amazon RSQL合并

用于动态查询情况的存储过程常识模式

SQL查询:合并2个表

SQL—如何根据2列填写缺失的值

基于多个字段删除Access中的重复记录,同时保留最低优先级

有没有办法在每次计算每一行的数据时更新2个值?

分组多输出访问查询问题

更新PostgreSQL 15中的JSON值

仅 for each 唯一ID返回一个元素,并仅返回最新连接的记录

在一个子查询中签入ID';S,如果未返回,则签入另一个子查询

如何根据几个条件 Select 值:如果满足一个范围的SUM,则对另一个范围求和

使用CTE在SNOWFLAKE中创建临时表

SQL根据另一列的顺序和值获取组中的最后一列

如何解释 SQL Server 中的 Foxpro 语法?

如何将 START 和 END 日期之间的日期差异作为 SQL 中的单独列获取

如何根据某个值在where子句中添加某个条件

我需要遍历权重值表并确定每个权重是否有效

使用SQL中另一个表的查询结果在表中查找记录

如何通过存储过程将 root 的下一个子 node 作为父 node ?

如何优化sql请求?