簡體   English   中英

在 SQL 中跨行分組/聚合數據范圍

[英]Grouping/aggregating data ranges across rows in SQL

我有以下日期范圍的產品所有權表:

在此處輸入圖像描述

輸入表的 DDL 可以在這里找到。

每個產品只能屬於一個組。 客戶不能在任何時間點擁有同一產品的兩個實例。

我們可以將上述產品所有權的時間線可視化如下:

產品所有權時間表

現在,我想計算范圍內每個組中擁有的產品數量,即:

輸出 1

最后,客戶擁有的產品總數和這些產品所屬的組數:

在此處輸入圖像描述

這是在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM