This pivot output section works fine in Oracle PL/SQL. It does not work in T-SQL.
I now need it to work in Snowflake SQL.
SELECT
*
FROM
(
SELECT
RACE, MNH_G, FNH_G, UNH_G, MH_G, FH_G, UH_G, MU_G, FU_G, UU_G, (TNH_G + THL_G + TU_G + TOTAL_G) AS TOTAL
FROM
(
SELECT
*
FROM
total_demographics
PIVOT
(
COUNT(line_number) as G
FOR (GENDER, ETHNICITY) IN (
('Male','Non-Hispanic') AS MNH,
('Female','Non-Hispanic') AS FNH,
('Unknown','Non-Hispanic') AS UNH,
('Male','Hispanic or Latino') AS MH,
('Female','Hispanic or Latino') AS FH,
('Unknown','Hispanic or Latino') AS UH,
('Male','Unknown') AS MU,
('Female','Unknown') AS FU,
('Unknown','Unknown') AS UU,
('Total','Non-Hispanic') AS TNH,
('Total','Hispanic or Latino') AS THL,
('Total','Unknown') AS TU,
('Total','Total') AS Total
)
)
ORDER BY (
case RACE
when 'American Indian or Alaska Native' then 0
when 'Asian' then 1
when 'Native Hawaiian or other Pacific Islander' then 2
when 'Black' then 3
when 'White' then 4
when 'More than one race' then 5
when 'Unknown' then 6
when 'Total' then 7
else
6
end
)
)
)
The output of the Oracle query is as follows:
RACE | MNH_G | FNH_G | UNH_G | MH_G | FH_G | UH_G | MU_G | FU_G | UU_G | TOTAL |
---|---|---|---|---|---|---|---|---|---|---|
American Indian or Alaska Native | 10 | 9 | 1 | 1 | 2 | 0 | 1 | 3 | 0 | 27 |
Asian | 90 | 80 | 1 | 0 | 2 | 0 | 2 | 3 | 0 | 178 |
Native Hawaiian or other Pacific Islander | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 4 |
White | 3703 | 3279 | 10 | 103 | 95 | 0 | 128 | 126 | 0 | 7475 |
More than one race | 6 | 6 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 14 |
Unknown | 412 | 6265 | 1 | 50 | 40 | 0 | 121 | 401 | 3 | 7443 |
Total | 4272 | 9667 | 13 | 159 | 149 | 0 | 294 | 588 | 3 | 15233 |
The Snowflake compiler doesn't like the "as G" column assignment in the first part of the pivot or the two part (GENDER, ETHNITICY) as well as the multiple values and column assignments in the FOR clause. It's okay with the ORDER BY clause.
How can I get the equivalent of the Oracle 2-dimensional FOR clause in Snowflake SQL (or for that matter T-SQL)?
You can combine multiple columns to array and then pivot:
-- sample data
CREATE OR REPLACE TABLE total_demographics AS
SELECT 'American Indian or Alaska Native' AS Race, 1 AS Line_Number,
'Male' AS Gender, 'Non-Hispanic' AS ETHNICITY;
-- main query
SELECT pvt.*
FROM (SELECT RACE, LINE_NUMBER, [GENDER, ETHNICITY] AS GE
FROM total_demographics) AS s
PIVOT(COUNT(LINE_NUMBER) FOR GE IN
(['Male','Non-Hispanic'],
['Female','Non-Hispanic'],
['Unknown','Non-Hispanic']
-- ...
)) AS pvt(RACE, MNH, FNH, UMH);
Output:
+----------------------------------+-----+-----+-----+
| RACE | MNH | FNH | UMH |
+----------------------------------+-----+-----+-----+
| American Indian or Alaska Native | 1 | 0 | 0 |
+----------------------------------+-----+-----+-----+