我如何聚合列,然后找出随时间变化最大的变化并显示最突出的变化?

How can I aggregate columns, then find out the biggest changes over time and display the most outstanding ones?

我是 SQL 的初学者,我想以绝对方式(积极和消极)跟踪一组州(有许多供应商可以在他们想要的每个州出售)门票出售的地方。

所以我有一个 state_table 这样的:

state_key state_name
1 Alabama
2 Connecticut
3 Maine

我有一个 ticket_sales table 这样的:

vender_key state_key sell_date no_of_sales
1 1 2021-01-01 27
1 2 2021-01-01 48
1 3 2021-01-01 69
2 1 2021-01-01 31
2 2 2021-01-01 41
3 2 2021-01-01 10
3 3 2021-01-01 15
1 1 2021-02-01 11
1 2 2021-02-01 21
1 3 2021-02-01 20
2 1 2021-02-01 67
2 2 2021-02-01 39
3 2 2021-02-01 13
3 3 2021-02-01 19
1 1 2021-03-01 77
1 2 2021-03-01 68
1 3 2021-03-01 59
2 1 2021-03-01 10
2 2 2021-03-01 11
3 2 2021-03-01 49
3 3 2021-03-01 54

当然,table实际上要长得多。

现在我想知道在整个时间范围内哪些州的总票房绝对差异最大。我要显示

按每个州最大和最小销售额之间的差异降序排列。

我的目标是了解哪些州的门票销售随着时间的推移发生了巨大变化,无论销售是积极还是消极发展。

因此,我需要先汇总每个州每个日期的供应商销售额,然后选择每个州的最高销售额和每个州对应的日期。然后,我必须对每个州的最低销售额和相应日期执行相同的操作。最后,我需要计算这两个数字之间的绝对差。

对我来说,不幸的是,SQL 中处理的聚合有点太多了。我尝试了一些带有 SUMGROUP BY 状态的代码,但我不知道如何告诉 SQL 聚合,然后通过选择每个状态的最高数字来正确计算(所以组合MAX 分别 MINGROUP BY),我对此感到困惑。

我的预期结果应该是:

state_name date_max sales_max date_min sales_min difference
Maine 2021-03-01 113 2021-02-01 39 74
Connecticut 2021-03-01 128 2021-02-01 73 55
Alabama 2021-03-01 87 2021-01-01 58 29

提前致谢!

您可以使用两个聚合来完成。首先为每个 state_key 找到 max/min 总和为 no_of_sales 的日期,然后有条件地按 state_key 聚合它。

select state_key 
  , max(case nmin when 1 then sell_date end) date_min
  , max(case nmin when 1 then n end) sales_min
  , max(case nmax when 1 then sell_date end) date_max
  , max(case nmax when 1 then n end) sales_max
  , max(case nmax when 1 then n end) - max(case nmin when 1 then n end ) delta
from ( 
    select state_key, sell_date, sum(no_of_sales) n
       , row_number() over(partition by state_key order by sum(no_of_sales)) nmin
       , row_number() over(partition by state_key order by sum(no_of_sales) desc) nmax
    from ticket_sales
    group by state_key, sell_date
) t
where nmin = 1 or nmax = 1
group by state_key
ORDER BY delta DESC 
FETCH FIRST 10 ROWS ONLY 

解码状态名称应该是最后一步。

select st.state_name, ts.date_min, ts.sales_min, ts.date_max, ts.sales_max,  ts.delta
from (
    select state_key 
      , max(case nmin when 1 then sell_date end) date_min
      , max(case nmin when 1 then n end) sales_min
      , max(case nmax when 1 then sell_date end) date_max
      , max(case nmax when 1 then n end) sales_max
      , max(case nmax when 1 then n end) - max(case nmin when 1 then n end ) delta
    from ( 
        select state_key, sell_date, sum(no_of_sales) n
           , row_number() over(partition by state_key order by sum(no_of_sales)) nmin
           , row_number() over(partition by state_key order by sum(no_of_sales) desc) nmax
        from ticket_sales
        group by state_key, sell_date
    ) t
    where nmin = 1 or nmax = 1
    group by state_key
    ORDER BY delta DESC 
    FETCH FIRST 10 ROWS ONLY 
) ts
join state_table st on ts.state_key = st.state_key