最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

sql - Transforming quantities into cumulative quantities in Snowflake - Stack Overflow

programmeradmin5浏览0评论

I have a table with example data like this:

Ref start_date end_date type seat
ABCDEF1111 2023-12-22 09:11:14 2024-01-31 23:59:59 recurring 1
ABCDEF1111 2024-01-02 06:42:55 2024-02-22 23:59:59 prorata 47
ABCDEF1111 2024-01-11 12:02:46 2024-02-22 23:59:59 prorata 24
ABCDEF1111 2024-12-22 00:00:00 2025-01-31 23:59:59 renew 72
ABCDEF1111 2024-12-23 08:23:54 cancelled -72

I have a table with example data like this:

Ref start_date end_date type seat
ABCDEF1111 2023-12-22 09:11:14 2024-01-31 23:59:59 recurring 1
ABCDEF1111 2024-01-02 06:42:55 2024-02-22 23:59:59 prorata 47
ABCDEF1111 2024-01-11 12:02:46 2024-02-22 23:59:59 prorata 24
ABCDEF1111 2024-12-22 00:00:00 2025-01-31 23:59:59 renew 72
ABCDEF1111 2024-12-23 08:23:54 cancelled -72

I'd like to use SQL in Snowflake to achieve this result:

Ref Month Begin End
ABCDEF1111 2023-11 0 0
ABCDEF1111 2023-12 0 1
ABCDEF1111 2024-01 1 72
ABCDEF1111 2024-02 72 72
ABCDEF1111 2024-03 72 72
ABCDEF1111 2024-04 72 72
ABCDEF1111 2024-05 72 72
ABCDEF1111 2024-06 72 72
ABCDEF1111 2024-07 72 72
ABCDEF1111 2024-08 72 72
ABCDEF1111 2024-09 72 72
ABCDEF1111 2024-10 72 72
ABCDEF1111 2024-11 72 72
ABCDEF1111 2024-12 72 72
ABCDEF1111 2025-01 72 72

Update: Some indications:

  • For the month 2023-12 we have 1 quantity, so we started the month with 1 and we end the month with 1.
  • For the month 2024-01 we started the month with 1 quantity (since the increase of 47 quantities was only made on the 2nd of January 2024) and ended the month of January with 1+47+24 = 72.
  • For the months 2024-03 to 2024-11 there were no operations, so we always start each month with 72 and end it with 72.
  • For the month 2024-12 we start with 72 (i.e. 72 at the first of the month) as there was an addition of 72 at 2024-12-22 and cancellation the next day -72 so we end the month with 72.
  • For month 2025-01 we start with 72 and end the month with 72.

Thank you in advance

Share Improve this question edited Feb 8 at 10:02 allaouakh asked Feb 7 at 17:19 allaouakhallaouakh 194 bronze badges 6
  • 1 Please update your question to explain how you’re generating the result table from your source data - what are the rules you are applying to that result in the rows you are showing? – NickW Commented Feb 7 at 17:42
  • your output does not include any logic as @NickW mentioned so its difficult to work with assumption, also please show your attempt. – samhita Commented Feb 7 at 17:45
  • Sorry, I modified my question by some indications. Thank you – allaouakh Commented Feb 7 at 19:07
  • For the month of 2023-12, should the begin be 0 instead of 1? since at the end of 2023-11 and 1st of 2023-12 there is no entry. First entry for 2023-12 is not on 1st but on 2023-12-22? – samhita Commented Feb 7 at 20:55
  • Yes 0 instead of 1 for 2023-12 – allaouakh Commented Feb 8 at 10:01
 |  Show 1 more comment

1 Answer 1

Reset to default 1

First we generate a row for each month.you can use a calendar table for this purpose, in this example I have used a custom generator to get a list of months for 15 months.

For each month, change in seat is calculated by summing all the seats for that month, note the months which does not have any seat will be assigned 0.

End for a month is calculated by summing seats for all previous months till that month for a REF(considering you would have multiple REFs).This is achieved by

  over (partition by ref order by month rows between unbounded preceding and current row) as end

Begin is the End value for the previous month, which is calculated by

lag(end, 1, 0) over (partition by ref order by month) as begin

Sample query

with distinct_refs as (
    select distinct ref
    from test_table
),
months as (
    select 
        d.ref,
        to_char(date_trunc('month', dateadd(month, seq4() - 1, '2024-01-01')), 'yyyy-mm') as month
    from 
        distinct_refs d
        cross join table(generator(rowcount => 15)) -- 15 months from 2023-11 to 2025-01
),
changes as (
    select 
        ref,
        date_trunc('month', start_date) as month,
        sum(seat) as seat_change
    from test_table
    group by ref, date_trunc('month', start_date)
),
monthly_seats as (
    select 
        m.ref, 
        m.month, 
        nvl(c.seat_change, 0) as seat_change
    from 
        months m
        left join changes c on m.ref = c.ref and m.month = to_char(c.month, 'yyyy-mm')
),
running_totals as (
    select 
        ref,
        month, 
        seat_change, 
        sum(seat_change) over (partition by ref order by month rows between unbounded preceding and current row) as end
    from monthly_seats
)
select 
    ref,
    month,
    lag(end, 1, 0) over (partition by ref order by month) as begin,
    end
from running_totals
order by ref, month;

Output

REF MONTH BEGIN END
ABCDEF1111 2023-12 0 1
ABCDEF1111 2024-01 1 72
ABCDEF1111 2024-02 72 72
ABCDEF1111 2024-03 72 72
ABCDEF1111 2024-04 72 72
ABCDEF1111 2024-05 72 72
ABCDEF1111 2024-06 72 72
ABCDEF1111 2024-07 72 72
ABCDEF1111 2024-08 72 72
ABCDEF1111 2024-09 72 72
ABCDEF1111 2024-10 72 72
ABCDEF1111 2024-11 72 72
ABCDEF1111 2024-12 72 72
ABCDEF1111 2025-01 72 72
ABCDEF1111 2025-02 72 72
发布评论

评论列表(0)

  1. 暂无评论