我有客户购买的记录。有时,客户在给定购买期间购买多个商品,有时他们仅购买单个商品。我想要逐行进行的工作是识别哪些购买事件已经发生(即不是按项目进行,而是以结账方式结账)。
源数据库的每一行都包含以下字段
cust_id, purchase_date, sku
因此,在给定交易期间购买三件商品的客户将会是这样的
1, 01/01/01, dog1
1, 01/01/01, cat1
1, 01/01/01, mouse1
1, 01/02/01, wolf1
1, 01/03/01, lion1
我想要的是
cust_id, purchase_date, sku, item_purchase_number_within_purchase, unique_purchase_date_across_dates
这看起来像是
1, 01/01/01, dog1, 1, 1
1, 01/01/01, cat1, 2, 1
1, 01/01/01, mouse1, 3, 1
1, 01/02/01, wolf1, 1, 2
1, 01/03/01, lion1, 1, 3
总之,在第一个日期,在第二个购买日期(2001年1月2日),任意购买的三件商品被认定为购买号码1,2和3,只购买了一件商品,但这是第二次购买活动,然后在第三个购买日期(2001年1月3日),购买了另一个单项。
我正在尝试在oracle10g中执行此操作。我不知道如何描述我正在完成的事情。
这是我到目前为止的SQL
选择 cust_id,purchase_date,sku,ROW_NUMBER()OVER(按购买数量分配ORDER BY sku) 从 [表]
由于
答案 0 :(得分:3)
您似乎希望dense_rank()
而不是row_number()
(或rank()
)来避免差距。将您的样本数据放在CTE中:
with t (cust_id, purchase_date, sku) as (
select 1, date '2001-01-01', 'dog1' from dual
union all select 1, date '2001-01-01', 'cat1' from dual
union all select 1, date '2001-01-01', 'mouse1' from dual
union all select 1, date '2001-01-02', 'wolf1' from dual
union all select 1, date '2001-01-03', 'lion1' from dual
)
select cust_id, purchase_date, sku,
dense_rank() over (partition by cust_id, purchase_date order by sku)
as item_within_purchase,
dense_rank() over (partition by cust_id order by purchase_date)
as purchase_event
from t;
CUST_ID PURCHASE_D SKU ITEM_WITHIN_PURCHASE PURCHASE_EVENT
---------- ---------- ------ -------------------- --------------
1 2001-01-01 cat1 1 1
1 2001-01-01 dog1 2 1
1 2001-01-01 mouse1 3 1
1 2001-01-02 wolf1 1 2
1 2001-01-03 lion1 1 3
第一个额外的列是按客户和日期分区,并按SKU的顺序排序;第二个仅由客户划分,并按日期排序。