[英]Grouping/aggregating data ranges across rows in SQL
我有以下日期范圍的產品所有權表:
輸入表的 DDL 可以在這里找到。
每個產品只能屬於一個組。 客戶不能在任何時間點擁有同一產品的兩個實例。
我們可以將上述產品所有權的時間線可視化如下:
現在,我想計算范圍內每個組中擁有的產品數量,即:
最后,客戶擁有的產品總數和這些產品所屬的組數:
這是在 Oracle 中,但如果有 ANSI SQL 中的代碼會很棒。
有什么提示嗎?
您可以通過將日期轉換為一列來跟蹤“in”和“out”來獲取產品的累積數量。 然后累積和得到產品的數量。
獲取組的數量更具挑戰性。 以下使用子查詢:
with dtes as (
select customer_id, date_from as dte, 1 as inc
from t
union all
select customer_id, date_to + 1, -1 as inc
from t
)
select customer_id, dte as date_from,
lead(dte) over (partition by customer_id order by dte) - 1 as date_to,
sum(sum(inc)) over (partition by customer_id order by dte),
(select count(distinct t2.prd_grp_id)
from t t2
where dtes.customer_id = t2.customer_id and
dtes.dte between t2.date_from and t2.date_to
) as num_groups
from dtes
group by customer_id, dte
order by customer_id, dte;
這是一個 db<>fiddle。
工作解決方案
OUTPUT #1
with dtes as (
select customer_id, prd_grp_id, date_from as dte, 1 as inc
from t
union all
select customer_id, prd_grp_id, date_to + 1, -1 as inc
from t
),
grps as (
select customer_id, prd_grp_id, dte as date_from,
lead(dte) over (partition by customer_id, prd_grp_id order by dte) - 1 as date_to,
sum(sum(inc)) over (partition by customer_id, prd_grp_id order by dte) as n_prods
from dtes
group by customer_id, prd_grp_id, dte
)
select * from grps where n_prods>0;
OUTPUT #2
with dtes as (
select customer_id, date_from as dte, 1 as inc
from t
union all
select customer_id, date_to + 1, -1 as inc
from t
),
totals as (
select customer_id, dte as date_from,
lead(dte) over (partition by customer_id order by dte) - 1 as date_to,
sum(sum(inc)) over (partition by customer_id order by dte) as num_prods,
(select count(distinct t2.prd_grp_id)
from t t2
where dtes.customer_id = t2.customer_id and
dtes.dte between t2.date_from and t2.date_to
) as num_groups
from dtes
group by customer_id, dte )
select * from totals where num_groups>0 order by customer_id, date_from;
謝謝@戈登林諾夫!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.