简体   繁体   中英

Flip a Multiple Columns and multiple rows in table in Snowflake

Unable to pivot multiple columns in snowflake and I would appreciate it if some one can help me:

I basically have the table attached in the screenshot in the left and need to change it to the format in the right. I wonder if pivot can work in this case?

my current code:

select 
CONCAT(RIGHT(TO_VARCHAR(YEAR(DATE)),2),'-Q',TO_VARCHAR(QUARTER(DATE)) ) closed_date,
IFNULL(sum(case when STAG='Closed' then REVENUE_AMOUNTS end),0) REVENUE AMER,
IFNULL(sum(case when STAG='Closed' then REVENUE_AMOUNTS end),0) REVENUE APAC,
IFNULL(sum(case when STAG='Closed' then REVENUE_AMOUNTS end),0) REVENUE EMEA

from REVENUE_TABLE
where 1=1
group by 1
order by 1 asc

link to screenshot

So assuming the SQL you have posted is more like this (with included fake data in a CTE)

WITH REVENUE_TABLE as (
    SELECT * FROM VALUES
    ('Closed', 1, '2020-01-01'::date, 'amer'),
    ('Closed', 2, '2020-04-01'::date, 'apac'),
    ('Closed', 3, '2020-08-01'::date, 'emea'),
    ('Closed', 4, '2021-01-01'::date, 'emea')
    v(stag, REVENUE_AMOUNTS, date, loc)
)
select 
    CONCAT(RIGHT(TO_VARCHAR(YEAR(DATE)),2),'-Q',TO_VARCHAR(QUARTER(DATE)) ) closed_date,
    ZEROIFNULL(sum(IFF(loc='amer' AND STAG='Closed', REVENUE_AMOUNTS, null))) as REVENUE_AMER,
    ZEROIFNULL(sum(IFF(loc='apac' AND STAG='Closed', REVENUE_AMOUNTS, null))) as REVENUE_APAC,
    ZEROIFNULL(sum(IFF(loc='emea' AND STAG='Closed', REVENUE_AMOUNTS, null))) as REVENUE_EMEA
from REVENUE_TABLE
group by 1
order by 1 asc

I swapped you CASE for an IFF and puting the which column does it belong in. And I swapped IFNULL(x, 0) for ZEROIFNULL(x) while longer, it more intent clear.

which gives results that look like your existing output:

CLOSED_DATE REVENUE_AMER REVENUE_APAC REVENUE_EMEA
20-Q1 1 0 0
20-Q2 0 2 0
20-Q3 0 0 3
21-Q1 0 0 4

so if that hold as "the way it is", then to get to "where you want to go" you need to find the distinct set of values or locations, and then join to your results based on that.

select l.loc,
    ZEROIFNULL(sum(IFF(r.cd='20-Q1', r.REVENUE_AMOUNTS, null))) as "20-Q1",
    ZEROIFNULL(sum(IFF(r.cd='20-Q2', r.REVENUE_AMOUNTS, null))) as "20-Q2",
    ZEROIFNULL(sum(IFF(r.cd='20-Q3', r.REVENUE_AMOUNTS, null))) as "20-Q3",
    ZEROIFNULL(sum(IFF(r.cd='21-Q1', r.REVENUE_AMOUNTS, null))) as "21-Q1"
from (
    select distinct loc 
    FROM REVENUE_TABLE
) as l
left join (
    select loc, 
        revenue_amounts,
        CONCAT(RIGHT(TO_VARCHAR(YEAR(DATE)),2),'-Q',TO_VARCHAR(QUARTER(DATE)) ) cd 
    FROM REVENUE_TABLE
    WHERE STAG='Closed'
) as r on l.loc = r.loc
group by 1
order by 1 asc;

gives:

LOC 20-Q1 20-Q2 20-Q3 21-Q1
amer 1 0 0 0
apac 0 2 0 0
emea 0 0 3 4

Now the downside of this pattern is you need to explicitly know the column names, but you have that problem in the PIVOT case as well. That could be worked around with Snowflake Scripting I believe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM