Pivot and summarize data and create new dynamic columns - sql

I have a table with the following structure
ID
Fiscal_Period
Account_ID
Opportunity_ID
Product_Type
Country
ARR
a1
FY21.12
014x4d
3xdjfr
Apple
US
5.3
a2
FY21.12
014x4d
3xdjfr
Orange
Canada
2.2
a3
FY20.5
014j3x
3xjas1
Tomato
US
1.1
a4
FY20.5
014j3x
3xjas2
Apple
Canada
4.2
I'm looking to create a version of the table that dynamically captures all the unique values in Product Type, Country, and Fiscal Period, and create custom summed ARR fields for each unique account ID:
accountID
ARR_APPLE_FY21.12
ARR_ORANGE_FY21.12
ARR_TOMATO_FY21.12
ARR_US_FY21.12
ARR_CANADA_FY21.12
ARR_TOTAL_FY21.12
ARR_APPLE_FY20.5
ARR_ORANGE_FY20.5
ARR_TOMATO_FY20.5
ARR_US_FY20.5
ARR_CANADA_FY20.5
ARR_TOTAL_FY20.5
014x4d
5.3
2.2
0
5.3
2.2
7.5
---
---
---
---
---
---
014j3x
0
0
0
0
0
0
4.2
---
1.1
1.1
4.2
5.3
I understand that this might not be the best way to organize data as it would make the dataset unnecessarily large and create a lot of fields. Primary purpose of this is to transform some data before I join it into a bigger account-level data set. I'm also open to performing this non-dynamically, as I've had some experience with Snowflake restricting my pivot abilities in the past.
I've tried using
SUM(CASE WHEN Product_Type = 'Apple' THEN ARR ELSE 0 END) AS 'ARR_Apple_FY' || SUBSTR(FISCAL_PERIOD, 3, 2) || '.' || SUBSTR(FISCAL_PERIOD, -2),
But this approach doesn't seem to work, as Snowflake doesn't like it when I use concatenates within an alias renaming. I'm ok with creating the columns statically ahead of time and grouping the sums into these columns, but would prefer to create them dynamically based on the unique values that exist within these fields.
Something like this is working, but I'm hoping for something more dynamic that also works in Snowflake.
SELECT
Account_ID,
SUM(CASE WHEN Product_Type = 'Apple' AND Fiscal_Period = 'FY21.12' THEN ARR ELSE 0 END) AS ARR_APPLE_FY2112,
SUM(CASE WHEN Product_Type = 'Orange' AND Fiscal_Period = 'FY21.12' THEN ARR ELSE 0 END) AS ARR_ORANGE_FY2112,
SUM(CASE WHEN Product_Type = 'Tomato' AND Fiscal_Period = 'FY21.12' THEN ARR ELSE 0 END) AS ARR_TOMATO_FY2112,
SUM(CASE WHEN Country = 'US' AND Fiscal_Period = 'FY21.12' THEN ARR ELSE 0 END) AS ARR_US_FY2112,
SUM(CASE WHEN Country = 'Canada' AND Fiscal_Period = 'FY21.12' THEN ARR ELSE 0 END) AS ARR_CANADA_FY2112,
SUM(CASE WHEN Fiscal_Period = 'FY21.12' THEN ARR ELSE 0 END) AS ARR_TOTAL_FY2112,
SUM(CASE WHEN Product_Type = 'Apple' AND Fiscal_Period = 'FY20.5' THEN ARR ELSE 0 END) AS ARR_APPLE_FY205,
SUM(CASE WHEN Product_Type = 'Orange' AND Fiscal_Period = 'FY20.5' THEN ARR ELSE 0 END) AS ARR_ORANGE_FY205,
SUM(CASE WHEN Product_Type = 'Tomato' AND Fiscal_Period = 'FY20.5' THEN ARR ELSE 0 END) AS ARR_TOMATO_FY205,
SUM(CASE WHEN Country = 'US' AND Fiscal_Period = 'FY20.5' THEN ARR ELSE 0 END) AS ARR_US_FY205,
SUM(CASE WHEN Country = 'Canada' AND Fiscal_Period = 'FY20.5' THEN ARR ELSE 0 END) AS ARR_CANADA_FY205,
SUM(CASE WHEN Fiscal_Period = 'FY20.5' THEN ARR ELSE 0 END) AS ARR_TOTAL_FY205
FROM myTable
GROUP BY Account_ID

I think you can make it dynamic if you do the following:
Pull distinct lists of Product Types and Fiscal Periods and store temp in temp tables.
Dynamically construct the SQL string you included in your question - you can do it by applying the LISTAGG() function to a cross-join of temp tables you built in step 1.
Execute the SQL stored in the string you built in Step 2 - e.g. via EXECUTE IMMEDIATE if you are using Snowflake Scripting.

Related

Column merge using sum in case Oracle APEX

I need help How can I merge the column into a single column, here is my code, is this method is correct. I want to get the count of the selected row in the table for the columns.
SELECT
CAT_MGR,
SUM ( case when CAT_MGR = 'A' THEN 1 else 0 end ) AS DESIGN,
sum (case when CAT_MGR = 'b' THEN 1 else 0 END) AS DESIGN,
sum (case when CAT_MGR = 'c' THEN 1 else 0 END) AS DESIGN
from Table_A
GROUP BY
CAT_MGR
Can you guys help me I'm a beginner at SQL.
Thank you in advance
If you want just one row in the resultset, then remove the group by clause. Then, if you want to count the three cat mgr together, you can use in:
select
sum(case when cat_mgr = 'a' then 1 else 0 end ) as design_a,
sum(case when cat_mgr = 'b' then 1 else 0 end ) as design_b,
sum(case when cat_mgr = 'c' then 1 else 0 end ) as design_c,
sum(case when cat_mgr in ('a', 'b', 'c') then 1 else 0 end ) as design
from Table_a
You just need to make addion like below in order to get one column "Design"
SELECT
CAT_MGR,
SUM (case when CAT_MGR = 'A' THEN 1 else 0 end )
+ sum (case when CAT_MGR = 'b' THEN 1 else 0 END)
+ sum (case when CAT_MGR = 'c' THEN 1 else 0 END)
AS DESIGN
from TJD_CORE_CATPB_TB
GROUP BY
CAT_MGR

Create a dataset that makes 0/1 flag any time a record is present

I've got a table that is designed to have 1 row per member per product usage per month. There are three products. Most people only use one product, but some us a combination of the others.
Ideally I'd like to have a result set that looks like:
However I'm only able to get it to show the same as it is now, but with 1's and 0's. So if a person used all three products, there would be three rows with 1's rather than one row with 3 1's.
Here's how the code looks right now:
WITH
dist_visit_typ_cte(visit_month, person_id, product_type) as
(select distinct visit_month, person_id, product_type
from product_transaction_table),
visit_count_cte (visit_month, person_id, prod_a_usage, prod_b_usage, prod_c_usage) as
(select distinct visit_month
,CASE WHEN product_type = 'A' then 1, else 0 end as prod_a_usage
,CASE WHEN product_type = 'B' then 1, else 0 end as prod_b_usage
,CASE WHEN product_type = 'C' then 1, else 0 end as prod_c_usage
from dist_visit_typ_cte
group by
visit_month
,CASE WHEN product_type = 'A' then 1, else 0
,CASE WHEN product_type = 'B' then 1, else 0
,CASE WHEN product_type = 'C' then 1, else 0
It's on an older version of SQL-Server (pre 2016).
You seem to be looking for conditional aggregation. The logic you want would look like:
select visit_month, person_id,
max(case when product_type = 'A' then 1 else 0 end) prod_a_usage,
max(case when product_type = 'B' then 1 else 0 end) prod_b_usage,
max(case when product_type = 'C' then 1 else 0 end) prod_c_usage
from dist_visit_typ_cte
group by visit_month, person_id

best way to generate long SQLite statements for a pivot

I need to create very long SQLite statements, pivots outputting thousands of columns.
I've resorted to doing this using string manipulation.
Just wondering if the SQLite API has a more elegant solution.
Example of desired output:
str = "SELECT sample_id
, SUM(CASE WHEN gear_id = 1 THEN counts ELSE 0 END) AS g1
, SUM(CASE WHEN gear_id = 2 THEN counts ELSE 0 END) AS g2
...
, SUM(CASE WHEN gear_id = N THEN counts ELSE 0 END) AS gN
FROM table1 GROUP BY sample_id"

Need to create a Totals report from oracle table data

I have a table in oracle similar to the the example table image that I need to have output the segregated totals as shown in the second example results image.
I need the sums of each item_type where A & B are just examples for a large number of possible items that can be added.
example table:
example results:
Any help would be appreciated. thanks
Use conditional aggregation:
SELECT
store,
SUM(CASE WHEN item_type = 'A' AND item_status = 'IN' THEN 1 ELSE 0 END) a_items_in,
SUM(CASE WHEN item_type = 'A' AND item_status = 'OUT' THEN 1 ELSE 0 END) a_items_out,
SUM(CASE WHEN item_type = 'B' AND item_status = 'IN' THEN 1 ELSE 0 END) b_items_in,
SUM(CASE WHEN item_type = 'B' AND item_status = 'OUT' THEN 1 ELSE 0 END) b_items_out
FROM mytable
GROUP BY store

Creating a New Table in Big Query from a log table and a reference table

I am new to big query and need to create a perm. table from a log file and a reference table. I am new to this, and did something wrong but can't figure out why. Please help.
log file (example)
-Event_Time,User_ID,Type
-1/1/2017,123_abc,a
-1/2/2017,123_bcd,b
-1/2/2017,123_abc,c
Reference Table (example)
-Type Partner
-a 1
-b 2
-c 3
-d 3
create table workarea.SummaryTable AS (
User_ID string,
TotalCount integer,
imps_time timestamp,
Partner integer)
insert into workarea.SummaryTable
select distinct User_ID,
COUNT(*) as TotalCount,
MIN(TIME) as imps_time,
SUM(case when Partner = '1' then 1 else 0 end) as 1,
SUM(case when Partner = '2' then 1 else 0 end) as 2,
SUM(case when Partner = '3' then 1 else 0 end) as 3
from workarea.logfile i
join workarea.referencetable r on i.Type=r.Type
where CID=10848805
group by USER_ID
.. and did something wrong but can't figure out why
Below points of failure I have identified so far
CREATE TABLE statement is not available in BigQuery
Data Manipulation Language allows you INSERT, DELETE and UPDATE only
You need to have table pre-created before you can manipulate with / insert data in it
Aliases cannot start with digits -
so below fragment is incorrect
SUM(CASE WHEN Partner = '1' THEN 1 ELSE 0 END) AS 1,
SUM(CASE WHEN Partner = '2' THEN 1 ELSE 0 END) AS 2,
SUM(CASE WHEN Partner = '3' THEN 1 ELSE 0 END) AS 3
you should rather use something like
SUM(CASE WHEN Partner = '1' THEN 1 ELSE 0 END) AS Partner_1,
SUM(CASE WHEN Partner = '2' THEN 1 ELSE 0 END) AS Partner_2,
SUM(CASE WHEN Partner = '3' THEN 1 ELSE 0 END) AS Partner_3
Some fields look like do not exist in referenced tables but you use them in final query: time in MIN(time) as imps_time and CID in WHERE CID=10848805
Schema of destination table has 4 fields - whereas schema of select statement has 6 fields. You should clear this out!! They must match!
Possible "solution" (BigQuery Standard SQL)
I assume (just for a sake of getting some progress here) the schema of your destination table in reality as something as below
User_ID STRING,
TotalCount INT64,
imps_time TIMESTAMP,
Partner_1 INT64,
Partner_2 INT64,
Partner_3 INT64
in this case - below query should produce correct result for insertion
#standardSQL
SELECT
User_ID,
COUNT(*) AS TotalCount,
MIN(Event_Time) AS imps_time,
SUM(CASE WHEN Partner = '1' THEN 1 ELSE 0 END) AS Partner_1,
SUM(CASE WHEN Partner = '2' THEN 1 ELSE 0 END) AS Partner_2,
SUM(CASE WHEN Partner = '3' THEN 1 ELSE 0 END) AS Partner_3
FROM `workarea.logfile` i
JOIN `workarea.referencetable` r ON i.Type=r.Type
-- WHERE CID=10848805
GROUP BY USER_ID