Files
email-tracker/external/duckdb/test/sql/pivot/test_unpivot.test
2025-10-24 19:21:19 -05:00

183 lines
4.3 KiB
SQL

# name: test/sql/pivot/test_unpivot.test
# description: Test standard SQL unpivot syntax
# group: [pivot]
# example taken from the snowflake docs
# https://docs.snowflake.com/en/sql-reference/constructs/unpivot
statement ok
PRAGMA enable_verification
statement ok
CREATE OR REPLACE TABLE monthly_sales(empid INT, dept TEXT, Jan INT, Feb INT, Mar INT, April INT);
statement ok
INSERT INTO monthly_sales VALUES
(1, 'electronics', 100, 200, 300, 100),
(2, 'clothes', 100, 300, 150, 200),
(3, 'cars', 200, 400, 100, 50);
# standard UNPIVOT
query IIII
SELECT * FROM monthly_sales
UNPIVOT(sales FOR month IN (jan, feb, mar, april))
ORDER BY empid;
----
1 electronics Jan 100
1 electronics Feb 200
1 electronics Mar 300
1 electronics April 100
2 clothes Jan 100
2 clothes Feb 300
2 clothes Mar 150
2 clothes April 200
3 cars Jan 200
3 cars Feb 400
3 cars Mar 100
3 cars April 50
# leaving out an entry works - it just does not unpivot that entry and leave it as a normal column
query IIIII
SELECT empid, dept, april, month, sales FROM monthly_sales
UNPIVOT(sales FOR month IN (jan, feb, mar))
ORDER BY empid;
----
1 electronics 100 Jan 100
1 electronics 100 Feb 200
1 electronics 100 Mar 300
2 clothes 200 Jan 100
2 clothes 200 Feb 300
2 clothes 200 Mar 150
3 cars 50 Jan 200
3 cars 50 Feb 400
3 cars 50 Mar 100
# alias in pivots
query IIII
SELECT * FROM monthly_sales
UNPIVOT(sales FOR month IN (jan AS January, feb AS February, mar AS March, april))
ORDER BY empid;
----
1 electronics January 100
1 electronics February 200
1 electronics March 300
1 electronics April 100
2 clothes January 100
2 clothes February 300
2 clothes March 150
2 clothes April 200
3 cars January 200
3 cars February 400
3 cars March 100
3 cars April 50
# alias the unpivot clause
query IIII
SELECT p.id, p.type, p.m, p.vals FROM monthly_sales
UNPIVOT(sales FOR month IN (jan, feb, mar, april)) AS p(id, type, m, vals);
----
1 electronics Jan 100
1 electronics Feb 200
1 electronics Mar 300
1 electronics April 100
2 clothes Jan 100
2 clothes Feb 300
2 clothes Mar 150
2 clothes April 200
3 cars Jan 200
3 cars Feb 400
3 cars Mar 100
3 cars April 50
# multi-column unpivot
query IIIII
SELECT empid, dept, month, sales_jan_feb, sales_mar_apr FROM monthly_sales
UNPIVOT((sales_jan_feb, sales_mar_apr) FOR month IN ((jan, feb), (mar, april)));
----
1 electronics Jan_Feb 100 200
1 electronics Mar_April 300 100
2 clothes Jan_Feb 100 300
2 clothes Mar_April 150 200
3 cars Jan_Feb 200 400
3 cars Mar_April 100 50
# multiple names in FOR clause
statement error
SELECT * FROM monthly_sales
UNPIVOT((sales_jan_feb, sales_mar_apr) FOR (month, month2) IN ((jan, feb), (mar, april)));
----
UNPIVOT requires a single column name
# count mismatch
statement error
SELECT * FROM monthly_sales
UNPIVOT(sales_jan_feb FOR month IN ((jan, feb), (mar, april)));
----
UNPIVOT name count mismatch
statement error
SELECT * FROM monthly_sales
UNPIVOT((a, b, c) FOR month IN ((jan, feb), (mar, april)));
----
UNPIVOT name count mismatch
statement error
SELECT empid, dept, month, sales_jan_feb, sales_mar_apr FROM monthly_sales
UNPIVOT((sales_jan_feb, sales_mar_apr) FOR month IN ((jan, feb), mar));
----
UNPIVOT value count mismatch
# unrecognized entry in unpivot
statement error
SELECT empid, dept, april, month, sales FROM monthly_sales
UNPIVOT(sales FOR month IN (jan, feb, mar, dec))
ORDER BY empid;
----
referenced in UNPIVOT but no matching entry was found in the table
# mix of types in pivot
statement error
SELECT * FROM monthly_sales
UNPIVOT(sales FOR month IN (empid, dept, jan, feb, mar, april))
----
an explicit cast is required
# unpivot over subquery
query IIIII
UNPIVOT (SELECT * FROM monthly_sales)
ON jan, feb, mar april
INTO
NAME month
VALUE sales;
----
1 electronics 100 Jan 100
1 electronics 100 Feb 200
1 electronics 100 april 300
2 clothes 200 Jan 100
2 clothes 200 Feb 300
2 clothes 200 april 150
3 cars 50 Jan 200
3 cars 50 Feb 400
3 cars 50 april 100
# empty IN clause
statement error
SELECT * FROM monthly_sales
UNPIVOT(sales FOR month IN ())
ORDER BY empid;
----
syntax error
statement error
SELECT * FROM monthly_sales
UNPIVOT(sales FOR month IN (''))
ORDER BY empid;
----
empty column name
statement error
SELECT * FROM monthly_sales
UNPIVOT(SUM(sales) FOR month IN (empid, dept, jan, feb, mar, april))
----
syntax error