should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,4 @@
add_library_unity(test_pivot OBJECT multi_statement_parsing.cpp)
set(ALL_OBJECT_FILES
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:test_pivot>
PARENT_SCOPE)

View File

@@ -0,0 +1,30 @@
#include "catch.hpp"
#include "test_helpers.hpp"
using namespace duckdb;
using namespace std;
// This test that the parser keeps statements in the right order, also when a multi-statement (i.e. a PIVOT is included
// See https://github.com/duckdb/duckdb/issues/18710
TEST_CASE("Parsing multiple statements including a PIVOT in one go results in a correctly ordered list", "[pivot][.]") {
DuckDB db(nullptr);
Connection con(db);
auto query = "PIVOT (SELECT 'a' AS col) ON col using first(col);SELECT 42;";
// Check that the SELECT 42 statement is last in the parsed statements list
auto statements = con.context->ParseStatements(query);
REQUIRE(statements.size() == 3);
// REQUIRE(statements.back()->query == "SELECT 42;");
// Execute the query
auto result = con.Query(query);
// We expect two results
REQUIRE(result);
REQUIRE(result->next);
REQUIRE(result->next->next == nullptr);
// The first result should be that of the PIVOT statement
REQUIRE(CHECK_COLUMN(result, 0, {"a"}));
// The second result should be 42
REQUIRE(CHECK_COLUMN(result->next, 0, {42}));
}

View File

@@ -0,0 +1,65 @@
# name: test/sql/pivot/optional_pivots.test
# description: Test pivot syntax with various optional statements
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Cities(Country VARCHAR, Name VARCHAR, Year INT, Population INT);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2000, 1005);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2010, 1065);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2020, 1158);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2000, 564);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2010, 608);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2020, 738);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2000, 8015);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2010, 8175);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2020, 8772);
query I
PIVOT Cities USING SUM(Population);
----
30100
query II rowsort
PIVOT Cities USING SUM(Population) GROUP BY Country;
----
NL 3228
US 26872
query I rowsort
PIVOT Cities GROUP BY Country;
----
NL
US
query IIII rowsort
PIVOT Cities ON Year GROUP BY Country;
----
NL 1 1 1
US 2 2 2
query IIII rowsort
PIVOT (SELECT Country, Year FROM Cities) ON Year;
----
NL 1 1 1
US 2 2 2

View File

@@ -0,0 +1,32 @@
# name: test/sql/pivot/pivot_15141.test
# description: Test #15141: order by with no pivot columns
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
create table p (col1 timestamp, col2 int);
statement ok
INSERT INTO p VALUES
('2024-12-04 09:30:01', 100),
('2024-12-04 09:30:02', 100),
('2024-12-04 09:30:03', 100),
('2024-12-04 09:30:04', 100),
('2024-12-04 09:30:05', 100),
('2024-12-04 09:30:06', 100),
('2024-12-04 09:30:07', 100),
('2024-12-04 09:30:08', 100);
query II
pivot p using sum (col2) group by col1 order by col1;
----
2024-12-04 09:30:01 100
2024-12-04 09:30:02 100
2024-12-04 09:30:03 100
2024-12-04 09:30:04 100
2024-12-04 09:30:05 100
2024-12-04 09:30:06 100
2024-12-04 09:30:07 100
2024-12-04 09:30:08 100

View File

@@ -0,0 +1,209 @@
# name: test/sql/pivot/pivot_6390.test
# description: Test #6390: PIVOT with CTE
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE cpb_tbl AS
WITH CPB(CPDH,NF,JG) AS (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
) FROM CPB;
query IIIII rowsort pivot
pivot cpb_tbl on nf using sum(jg)group by cpdh
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
pivot CPB on nf IN (2010, 2017, 2018, 2022) using sum(jg)group by cpdh
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
pivot CPB on nf using sum(jg)group by cpdh
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
SELECT *
FROM (pivot CPB on nf using sum(jg)group by cpdh)
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
from CPB pivot (sum(jg) for nf in (2010, 2017, 2018, 2022) group by cpdh)
----
require no_alternative_verify
# nested CTEs with overlapping names
query IIIII rowsort pivot
WITH CPB AS (SELECT 42)
SELECT *
FROM (
WITH CPB(CPDH,NF,JG) AS (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
pivot CPB on nf using sum(jg) group by cpdh)
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS MATERIALIZED (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
pivot CPB on nf IN (2010, 2017, 2018, 2022) using sum(jg)group by cpdh
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS MATERIALIZED (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
pivot CPB on nf using sum(jg)group by cpdh
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS MATERIALIZED (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
SELECT *
FROM (pivot CPB on nf using sum(jg)group by cpdh)
----
query IIIII rowsort pivot
WITH CPB(CPDH,NF,JG) AS MATERIALIZED (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
from CPB pivot (sum(jg) for nf in (2010, 2017, 2018, 2022) group by cpdh)
----
# nested CTEs with overlapping names
query IIIII rowsort pivot
WITH CPB AS (SELECT 42)
SELECT *
FROM (
WITH CPB(CPDH,NF,JG) AS MATERIALIZED (
SELECT 'C1',2022,10
UNION ALL
SELECT 'C1',2018,20
UNION ALL
SELECT 'C1',2017,0
UNION ALL
SELECT 'C2',2022,10
UNION ALL
SELECT 'C2',2010,30
UNION ALL
SELECT 'C3',2010,80
)
pivot CPB on nf using sum(jg) group by cpdh)
----

View File

@@ -0,0 +1,98 @@
# name: test/sql/pivot/pivot_bigquery.test
# description: Tests from the bigquery docs
# group: [pivot]
# https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#pivot_operator
# https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#unpivot_operator
# pivot
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Produce AS
SELECT 'Kale' as product, 51 as sales, 'Q1' as quarter, 2020 as year UNION ALL
SELECT 'Kale', 23, 'Q2', 2020 UNION ALL
SELECT 'Kale', 45, 'Q3', 2020 UNION ALL
SELECT 'Kale', 3, 'Q4', 2020 UNION ALL
SELECT 'Kale', 70, 'Q1', 2021 UNION ALL
SELECT 'Kale', 85, 'Q2', 2021 UNION ALL
SELECT 'Apple', 77, 'Q1', 2020 UNION ALL
SELECT 'Apple', 0, 'Q2', 2020 UNION ALL
SELECT 'Apple', 1, 'Q1', 2021
query IIIIII
SELECT * FROM Produce
PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2', 'Q3', 'Q4'))
ORDER BY ALL
----
Apple 2020 77 0 NULL NULL
Apple 2021 1 NULL NULL NULL
Kale 2020 51 23 45 3
Kale 2021 70 85 NULL NULL
query IIIII
SELECT * FROM
(SELECT product, sales, quarter FROM Produce)
PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2', 'Q3', 'Q4'))
ORDER BY ALL
----
Apple 78 0 NULL NULL
Kale 121 108 45 3
query IIII
SELECT * FROM
(SELECT product, sales, quarter FROM Produce)
PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2', 'Q3'))
ORDER BY ALL
----
Apple 78 0 NULL
Kale 121 108 45
query III
SELECT * FROM
(SELECT sales, quarter FROM Produce)
PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2', 'Q3'))
ORDER BY ALL
----
199 108 45
query IIIII
SELECT * FROM
(SELECT product, sales, quarter FROM Produce)
PIVOT(SUM(sales) total_sales, COUNT(*) num_records FOR quarter IN ('Q1', 'Q2'))
ORDER BY ALL
----
Apple 78 2 0 1
Kale 121 2 108 2
statement ok
CREATE OR REPLACE TABLE Produce AS
SELECT 'Kale' as product, 51 as Q1, 23 as Q2, 45 as Q3, 3 as Q4 UNION ALL
SELECT 'Apple', 77, 0, 25, 2
query III
SELECT * FROM Produce
UNPIVOT(sales FOR quarter IN (Q1, Q2, Q3, Q4))
ORDER BY ALL
----
Apple Q1 77
Apple Q2 0
Apple Q3 25
Apple Q4 2
Kale Q1 51
Kale Q2 23
Kale Q3 45
Kale Q4 3
query IIII
SELECT product, first_half_sales, second_half_sales, semesters FROM Produce
UNPIVOT(
(first_half_sales, second_half_sales)
FOR semesters
IN ((Q1, Q2) AS 'semester_1', (Q3, Q4) AS 'semester_2'))
----
Kale 51 23 semester_1
Kale 45 3 semester_2
Apple 77 0 semester_1
Apple 25 2 semester_2

View File

@@ -0,0 +1,34 @@
# name: test/sql/pivot/pivot_case_insensitive.test
# description: Test case insensitivity in pivot names
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Cities (Name VARCHAR, id INTEGER);
INSERT INTO Cities VALUES ('Test', 1);
INSERT INTO Cities VALUES ('test',2);
statement ok
SET pivot_filter_threshold=1;
query II
FROM Cities
PIVOT (
array_agg(id)
FOR
name IN ('test','Test')
);
----
[2] [1]
query IIII
FROM Cities
PIVOT (
array_agg(id), sum(id)
FOR
name IN ('test','Test')
);
----
[2] 2 [1] 1

View File

@@ -0,0 +1,170 @@
# name: test/sql/pivot/pivot_databricks.test
# description: Tests from the databricks docs
# group: [pivot]
# https://docs.databricks.com/sql/language-manual/sql-ref-syntax-qry-select-pivot.html
statement ok
PRAGMA enable_verification
statement ok
CREATE TEMP VIEW sales(year, quarter, region, sales) AS
VALUES (2018, 1, 'east', 100),
(2018, 2, 'east', 20),
(2018, 3, 'east', 40),
(2018, 4, 'east', 40),
(2019, 1, 'east', 120),
(2019, 2, 'east', 110),
(2019, 3, 'east', 80),
(2019, 4, 'east', 60),
(2018, 1, 'west', 105),
(2018, 2, 'west', 25),
(2018, 3, 'west', 45),
(2018, 4, 'west', 45),
(2019, 1, 'west', 125),
(2019, 2, 'west', 115),
(2019, 3, 'west', 85),
(2019, 4, 'west', 65);
query IIIIII rowsort
SELECT year, region, q1, q2, q3, q4
FROM sales
PIVOT (sum(sales)
FOR quarter
IN (1 AS q1, 2 AS q2, 3 AS q3, 4 AS q4));
----
2018 east 100 20 40 40
2018 west 105 25 45 45
2019 east 120 110 80 60
2019 west 125 115 85 65
# multiple matches with aliases
query IIIIIIIII rowsort
SELECT year, q1_east, q1_west, q2_east, q2_west, q3_east, q3_west, q4_east, q4_west
FROM sales
PIVOT (sum(sales)
FOR (quarter, region)
IN ((1, 'east') AS q1_east, (1, 'west') AS q1_west, (2, 'east') AS q2_east, (2, 'west') AS q2_west,
(3, 'east') AS q3_east, (3, 'west') AS q3_west, (4, 'east') AS q4_east, (4, 'west') AS q4_west));
----
2018 100 105 20 25 40 45 40 45
2019 120 125 110 115 80 85 60 65
# inconsistent amount of names
statement error
SELECT year, q1_east, q1_west, q2_east, q2_west, q3_east, q3_west, q4_east, q4_west
FROM sales
PIVOT (sum(sales)
FOR (quarter, region, too_many_names)
IN ((1, 'east') AS q1_east, (1, 'west') AS q1_west, (2, 'east') AS q2_east, (2, 'west') AS q2_west,
(3, 'east') AS q3_east, (3, 'west') AS q3_west, (4, 'east') AS q4_east, (4, 'west') AS q4_west));
----
inconsistent amount of rows
# inconsistent amount of rows in the IN list
statement error
SELECT year, q1_east, q1_west, q2_east, q2_west, q3_east, q3_west, q4_east, q4_west
FROM sales
PIVOT (sum(sales)
FOR (quarter, region)
IN ((1, 'east', 'west') AS q1_east, (1, 'west') AS q1_west, (2, 'east') AS q2_east, (2, 'west') AS q2_west,
(3, 'east') AS q3_east, (3, 'west') AS q3_west, (4, 'east') AS q4_east, (4, 'west') AS q4_west));
----
inconsistent amount of rows
# duplicate values in IN list
statement error
SELECT *
FROM sales
PIVOT (sum(sales)
FOR (quarter, region)
IN ((1, 'east') AS q1_east, (1, 'east') AS q1_east_2));
----
specified multiple times in the IN clause
query IIIII rowsort
SELECT year, q1, q2, q3, q4
FROM (SELECT year, quarter, sales FROM sales) AS s
PIVOT (sum(sales)
FOR quarter
IN (1 AS q1, 2 AS q2, 3 AS q3, 4 AS q4));
----
2018 205 45 85 85
2019 245 225 165 125
# multiple aggregations
query IIIIIIIII rowsort
SELECT year, q1_total, q1_avg, q2_total, q2_avg, q3_total, q3_avg, q4_total, q4_avg
FROM (SELECT year, quarter, sales FROM sales) AS s
PIVOT (sum(sales) AS total, avg(sales) AS avg
FOR quarter
IN (1 AS q1, 2 AS q2, 3 AS q3, 4 AS q4));
----
2018 205 102.5 45 22.5 85 42.5 85 42.5
2019 245 122.5 225 112.5 165 82.5 125 62.5
# multiple aggregations without aliases
query IIIIIIIII rowsort
SELECT *
FROM (SELECT year, quarter, sales FROM sales) AS s
PIVOT (sum(sales), avg(sales)
FOR quarter
IN (1 AS q1, 2 AS q2, 3 AS q3, 4 AS q4));
----
2018 205 102.5 45 22.5 85 42.5 85 42.5
2019 245 122.5 225 112.5 165 82.5 125 62.5
# unpivot
statement ok
CREATE OR REPLACE TEMPORARY VIEW sales(location, year, q1, q2, q3, q4) AS
VALUES ('Toronto' , 2020, 100 , 80 , 70, 150),
('San Francisco', 2020, NULL, 20 , 50, 60),
('Toronto' , 2021, 110 , 90 , 80, 170),
('San Francisco', 2021, 70 , 120, 85, 105);
query IIII rowsort
SELECT *
FROM sales UNPIVOT INCLUDE NULLS
(sales FOR quarter IN (q1 AS "Jan-Mar",
q2 AS "Apr-Jun",
q3 AS "Jul-Sep",
q4 AS "Oct-Dec"));
----
San Francisco 2020 Apr-Jun 20
San Francisco 2020 Jan-Mar NULL
San Francisco 2020 Jul-Sep 50
San Francisco 2020 Oct-Dec 60
San Francisco 2021 Apr-Jun 120
San Francisco 2021 Jan-Mar 70
San Francisco 2021 Jul-Sep 85
San Francisco 2021 Oct-Dec 105
Toronto 2020 Apr-Jun 80
Toronto 2020 Jan-Mar 100
Toronto 2020 Jul-Sep 70
Toronto 2020 Oct-Dec 150
Toronto 2021 Apr-Jun 90
Toronto 2021 Jan-Mar 110
Toronto 2021 Jul-Sep 80
Toronto 2021 Oct-Dec 170
statement ok
CREATE OR REPLACE TEMPORARY VIEW oncall
(year, week, area , name1 , email1 , phone1 , name2 , email2 , phone2) AS
VALUES (2022, 1 , 'frontend', 'Freddy', 'fred@alwaysup.org' , 15551234567, 'Fanny' , 'fanny@lwaysup.org' , 15552345678),
(2022, 1 , 'backend' , 'Boris' , 'boris@alwaysup.org', 15553456789, 'Boomer', 'boomer@lwaysup.org', 15554567890),
(2022, 2 , 'frontend', 'Franky', 'frank@lwaysup.org' , 15555678901, 'Fin' , 'fin@alwaysup.org' , 15556789012),
(2022, 2 , 'backend' , 'Bonny' , 'bonny@alwaysup.org', 15557890123, 'Bea' , 'bea@alwaysup.org' , 15558901234);
query IIIIIII rowsort
SELECT *
FROM oncall UNPIVOT ((name, email, phone) FOR precedence IN ((name1, email1, phone1) AS primary,
(name2, email2, phone2) AS secondary));
----
2022 1 backend primary Boris boris@alwaysup.org 15553456789
2022 1 backend secondary Boomer boomer@lwaysup.org 15554567890
2022 1 frontend primary Freddy fred@alwaysup.org 15551234567
2022 1 frontend secondary Fanny fanny@lwaysup.org 15552345678
2022 2 backend primary Bonny bonny@alwaysup.org 15557890123
2022 2 backend secondary Bea bea@alwaysup.org 15558901234
2022 2 frontend primary Franky frank@lwaysup.org 15555678901
2022 2 frontend secondary Fin fin@alwaysup.org 15556789012

View File

@@ -0,0 +1,29 @@
# name: test/sql/pivot/pivot_empty.test
# description: Test SQL pivot on an empty table
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Cities(Country VARCHAR, Name VARCHAR, Year INT, Population INT);
query II
PIVOT Cities ON Country USING SUM(Population);
----
query I
PIVOT Cities ON Country, Name USING SUM(Population);
----
query III
PIVOT Cities ON Country IN ('xx') USING SUM(Population);
----
query II
PIVOT Cities ON (Country, Name) IN ('xx') USING SUM(Population);
----
query IIII
PIVOT Cities ON Country IN ('xx', 'yy') USING SUM(Population);
----

View File

@@ -0,0 +1,66 @@
# name: test/sql/pivot/pivot_enum.test
# description: Test SQL pivot syntax using an enum instead of an IN list
# group: [pivot]
statement ok
PRAGMA enable_verification
# pivot using an enum
statement ok
CREATE OR REPLACE TABLE monthly_sales(empid INT, amount INT, month TEXT);
statement ok
INSERT INTO monthly_sales VALUES
(1, 10000, 'JAN'),
(1, 400, 'JAN'),
(2, 4500, 'JAN'),
(2, 35000, 'JAN'),
(1, 5000, 'FEB'),
(1, 3000, 'FEB'),
(2, 200, 'FEB'),
(2, 90500, 'FEB'),
(1, 6000, 'MAR'),
(1, 5000, 'MAR'),
(2, 2500, 'MAR'),
(2, 9500, 'MAR'),
(1, 8000, 'APR'),
(1, 10000, 'APR'),
(2, 800, 'APR'),
(2, 4500, 'APR');
statement ok
CREATE TYPE unique_months AS ENUM (SELECT DISTINCT month FROM monthly_sales ORDER BY
CASE month WHEN 'JAN' THEN 1 WHEN 'FEB' THEN 2 WHEN 'MAR' THEN 3 ELSE 4 END);
query IIIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN unique_months)
AS p
ORDER BY EMPID;
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
# enum does not exist
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN unique_monthsx)
AS p
ORDER BY EMPID;
----
unique_monthsx
statement ok
CREATE TYPE not_an_enum AS VARCHAR;
# enum does not exist
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN not_an_enum)
AS p
ORDER BY EMPID;
----
Pivot must reference an ENUM type

View File

@@ -0,0 +1,46 @@
# name: test/sql/pivot/pivot_errors.test
# description: Test pivot errors
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE test(i INT, j VARCHAR);
statement error
PIVOT test ON j IN ('a', 'b') USING SUM(test.i);
----
PIVOT expression cannot contain qualified columns
statement ok
SET pivot_filter_threshold=0
statement error
PIVOT test ON j IN ('a', 'b') USING get_current_timestamp();
----
no aggregates were found
statement ok
SET pivot_filter_threshold=100
statement error
PIVOT test ON j IN ('a', 'b') USING get_current_timestamp();
----
no aggregates were found
statement error
PIVOT test ON j IN ('a', 'b') USING sum(41) over ();
----
cannot contain window functions
statement error
PIVOT test ON j IN ('a', 'b') USING sum(sum(41) over ());
----
cannot contain window functions
# empty pivot clause
statement error
FROM tbl PIVOT (c FOR IN enum_val);
----
Parser Error

View File

@@ -0,0 +1,206 @@
# name: test/sql/pivot/pivot_example.test_slow
# description: Test SQL pivot examples for documentation
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Cities(Country VARCHAR, Name VARCHAR, Year INT, Population INT);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2000, 1005);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2010, 1065);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2020, 1158);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2000, 564);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2010, 608);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2020, 738);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2000, 8015);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2010, 8175);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2020, 8772);
statement ok
SET pivot_filter_threshold=99
loop i 0 2
statement ok
PIVOT Cities ON Country, Name IN ('xx') USING SUM(Population);
query IIIII rowsort
PIVOT Cities ON Year USING SUM(Population);
----
NL Amsterdam 1005 1065 1158
US New York City 8015 8175 8772
US Seattle 564 608 738
query IIIII rowsort
SELECT Country, Name, "2000_total_pop", "2010_total_pop", "2020_total_pop" FROM (PIVOT Cities ON Year USING SUM(Population) as total_pop)
----
NL Amsterdam 1005 1065 1158
US New York City 8015 8175 8772
US Seattle 564 608 738
query IIIII rowsort
PIVOT_WIDER Cities ON Year USING SUM(Population);
----
NL Amsterdam 1005 1065 1158
US New York City 8015 8175 8772
US Seattle 564 608 738
# sql syntax
query IIIII rowsort
FROM Cities PIVOT (SUM(Population) FOR Year IN (2000, 2010, 2020));
----
NL Amsterdam 1005 1065 1158
US New York City 8015 8175 8772
US Seattle 564 608 738
query IIII rowsort
PIVOT Cities ON Year IN (2000, 2020) USING SUM(Population);
----
NL Amsterdam 1005 1158
US New York City 8015 8772
US Seattle 564 738
query IIII rowsort
PIVOT Cities ON Year USING SUM(Population) GROUP BY Country;
----
NL 1005 1065 1158
US 8579 8783 9510
# use pivots in a set operation
statement ok
PIVOT Cities ON Year USING SUM(Population)
UNION ALL BY NAME
PIVOT Cities ON Name USING SUM(Population);
# join on pivots
query IIIIIII rowsort
FROM
(PIVOT Cities ON Year USING SUM(Population) GROUP BY Country)
JOIN
(PIVOT Cities ON Name USING SUM(Population) GROUP BY Country)
USING (Country)
----
NL 1005 1065 1158 3228 NULL NULL
US 8579 8783 9510 NULL 24962 1910
query II rowsort
PIVOT Cities ON (Country, Name) IN ('xx') USING SUM(Population);
----
2000 NULL
2010 NULL
2020 NULL
query IIIIIII rowsort
PIVOT (SELECT Country, Population, Year FROM Cities) ON Year USING SUM(Population) as sum_pop, count(population) as count_pop,;
----
NL 1005 1 1065 1 1158 1
US 8579 2 8783 2 9510 2
# multiple pivots
query IIIIIII rowsort
PIVOT Cities ON Year USING SUM(Population) as sum_pop, count(population) as count_pop, GROUP BY Country;
----
NL 1005 1 1065 1 1158 1
US 8579 2 8783 2 9510 2
query IIIIIII rowsort
PIVOT Cities ON Year USING SUM(Population), count(population) GROUP BY Country;
----
NL 1005 1 1065 1 1158 1
US 8579 2 8783 2 9510 2
# pivot order by/limit
query IIII
PIVOT Cities ON Year USING SUM(Population) GROUP BY country ORDER BY country desc
----
US 8579 8783 9510
NL 1005 1065 1158
query IIII
PIVOT Cities ON Year USING SUM(Population) GROUP BY country ORDER BY country desc LIMIT 1
----
US 8579 8783 9510
query IIII
PIVOT Cities ON Year USING SUM(Population) GROUP BY country ORDER BY country LIMIT 1
----
NL 1005 1065 1158
query IIII
PIVOT Cities ON Year USING SUM(Population) GROUP BY country ORDER BY country LIMIT 1 OFFSET 1
----
US 8579 8783 9510
query IIII
PIVOT Cities ON Year USING SUM(Population) GROUP BY country ORDER BY ALL
----
NL 1005 1065 1158
US 8579 8783 9510
statement ok
SET pivot_filter_threshold=0
endloop
# unpivot
statement ok
CREATE TABLE PivotedCities AS PIVOT Cities ON Year USING SUM(Population);
query IIII nosort unpivot
UNPIVOT PivotedCities ON 2000, 2010, 2020 INTO NAME Year VALUE Population;
----
query IIII nosort unpivot
FROM PivotedCities UNPIVOT(Population FOR Year IN (2000, 2010, 2020));
----
query IIII nosort unpivot
UNPIVOT PivotedCities ON 2000, 2010, 2020;
----
query IIII nosort unpivot
UNPIVOT PivotedCities ON COLUMNS('\d+');
----
query IIII nosort unpivot
UNPIVOT PivotedCities ON * EXCLUDE (Country, Name)
----
query IIII nosort unpivot
PIVOT_LONGER PivotedCities ON 2000, 2010, 2020;
# unpivot order by/limit
query IIII
UNPIVOT PivotedCities ON 2000, 2010, 2020 ORDER BY ALL DESC LIMIT 1
----
US Seattle 2020 738
query IIII
UNPIVOT PivotedCities ON 2000, 2010, 2020 ORDER BY ALL LIMIT 1
----
NL Amsterdam 2000 1005
query IIII
UNPIVOT PivotedCities ON 2000, 2010, 2020 ORDER BY 1, 3 LIMIT 1 OFFSET 1
----
NL Amsterdam 2010 1065

View File

@@ -0,0 +1,111 @@
# name: test/sql/pivot/pivot_expressions.test
# description: Test SQL pivot expressions
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Cities(Country VARCHAR, Name VARCHAR, Year INT, Population INT);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2000, 1005);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2010, 1065);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2020, 1158);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2000, 564);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2010, 608);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2020, 738);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2000, 8015);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2010, 8175);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2020, 8772);
query IIII rowsort
PIVOT Cities ON Country || '_' || Name USING SUM(Population) GROUP BY Year;
----
2000 1005 8015 564
2010 1065 8175 608
2020 1158 8772 738
query II rowsort
PIVOT Cities ON (CASE WHEN Country='NL' THEN NULL ELSE Country END) USING SUM(Population) GROUP BY Year;
----
2000 8579
2010 8783
2020 9510
# we allow expressions in the aggregate as well
query IIII rowsort
PIVOT Cities ON Country || '_' || Name USING COALESCE(SUM(Population), 0) GROUP BY Year;
----
2000 1005 8015 564
2010 1065 8175 608
2020 1158 8772 738
# casts
query IIII rowsort
PIVOT Cities ON Country || '_' || Name USING SUM(Population)::VARCHAR GROUP BY Year;
----
2000 1005 8015 564
2010 1065 8175 608
2020 1158 8772 738
# functions
query IIII rowsort
PIVOT Cities ON Country || '_' || Name USING SUM(Population) + 42 GROUP BY Year;
----
2000 1047 8057 606
2010 1107 8217 650
2020 1200 8814 780
# we cannot have multiple aggregates
statement error
PIVOT Cities ON Country || '_' || Name USING SUM(Population) + COUNT(*) GROUP BY Year;
----
Pivot expression must contain exactly one aggregate
# columns can only be referenced within the aggregate
statement error
PIVOT Cities ON Country || '_' || Name USING SUM(Population) + Population GROUP BY Year;
----
Columns can only be referenced within the aggregate of a PIVOT expression
statement error
PIVOT Cities ON min(Country) over () USING SUM(Population) GROUP BY Year;
----
cannot contain window functions
statement error
PIVOT Cities ON min(Country) USING SUM(Population) GROUP BY Year;
----
cannot contain aggregates
statement error
PIVOT Cities ON NULL USING SUM(Population) GROUP BY Year;
----
Cannot pivot on constant value
statement error
PIVOT Cities ON 'hello world' USING SUM(Population) GROUP BY Year;
----
Cannot pivot on constant value
statement error
PIVOT Cities ON (SELECT COUNTRY) USING SUM(Population) GROUP BY Year;
----
Cannot pivot on subquery

View File

@@ -0,0 +1,28 @@
# name: test/sql/pivot/pivot_generated.test
# description: Test pivot over generated columns
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Product(DaysToManufacture int, StandardCost int GENERATED ALWAYS AS (DaysToManufacture * 5));
statement ok
INSERT INTO Product VALUES (0), (1), (2), (4);
query IIIIII
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days,
"0", "1", "2", "3", "4"
FROM
(
SELECT DaysToManufacture, StandardCost
FROM Product
) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN (0, 1, 2, 3, 4)
) AS PivotTable;
----
AverageCost 0.0 5.0 10.0 NULL 20.0

View File

@@ -0,0 +1,50 @@
# name: test/sql/pivot/pivot_in_boolean.test
# description: Issue #8596 - Pivot with IN clause doesn't work for a boolean column
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Cities(Country VARCHAR, Name VARCHAR, Year INT, Population INT);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2000, 1005);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2010, 1065);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2020, 1158);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2000, 564);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2010, 608);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2020, 738);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2000, 8015);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2010, 8175);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2020, 8772);
query III rowsort
pivot cities on (Country='NL') using avg(Population) group by name;
----
Amsterdam NULL 1076.0
New York City 8320.666666666666 NULL
Seattle 636.6666666666666 NULL
query III rowsort
pivot cities on (Country='NL') in (false, true) using avg(Population) group by name;
----
Amsterdam NULL 1076.0
New York City 8320.666666666666 NULL
Seattle 636.6666666666666 NULL

View File

@@ -0,0 +1,63 @@
# name: test/sql/pivot/pivot_in_subquery.test
# description: Test SQL pivot with a subquery in the IN clause
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Cities(Country VARCHAR, Name VARCHAR, Year INT, Population INT);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2000, 1005);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2010, 1065);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2020, 1158);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2000, 564);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2010, 608);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2020, 738);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2000, 8015);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2010, 8175);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2020, 8772);
# order the pivot columns
query IIIII rowsort
PIVOT Cities ON Year IN (SELECT Year FROM Cities ORDER BY Year DESC) USING SUM(Population);
----
NL Amsterdam 1158 1065 1005
US New York City 8772 8175 8015
US Seattle 738 608 564
query IIIII rowsort
PIVOT Cities ON Year IN (SELECT YEAR FROM (SELECT Year, SUM(POPULATION) AS popsum FROM Cities GROUP BY Year ORDER BY popsum DESC)) USING SUM(Population);
----
NL Amsterdam 1158 1065 1005
US New York City 8772 8175 8015
US Seattle 738 608 564
query IIIII rowsort
PIVOT Cities ON Year IN (SELECT '2010' UNION ALL SELECT '2000' UNION ALL SELECT '2020') USING SUM(Population);
----
NL Amsterdam 1065 1005 1158
US New York City 8175 8015 8772
US Seattle 608 564 738
statement error
PIVOT Cities ON Year IN (SELECT xx FROM Cities) USING SUM(Population);
----
<REGEX>:Binder Error.*Referenced column.*not found.*

View File

@@ -0,0 +1,38 @@
# name: test/sql/pivot/pivot_operator_expression.test
# description: Test expressions in pivot syntax
# group: [pivot]
statement ok
PRAGMA enable_verification
# pivot using an enum
statement ok
CREATE OR REPLACE TABLE monthly_sales(empid INT, amount INT, month TEXT);
statement ok
INSERT INTO monthly_sales VALUES
(1, 10000, '1-JAN'),
(1, 400, '1-JAN'),
(2, 4500, '1-JAN'),
(2, 35000, '1-JAN'),
(1, 5000, '2-FEB'),
(1, 3000, '2-FEB'),
(2, 200, '2-FEB'),
(2, 90500, '2-FEB'),
(2, 2500, '3-MAR'),
(2, 9500, '3-MAR'),
(1, 8000, '4-APR'),
(1, 10000, '4-APR'),
(2, 800, '4-APR'),
(2, 4500, '4-APR');
query IIIII rowsort
PIVOT monthly_sales ON MONTH USING COALESCE(SUM(AMOUNT), 0)
----
1 10400 8000 0 18000
2 39500 90700 12000 5300
query I
SELECT mode(column_type) FROM (DESCRIBE PIVOT monthly_sales ON MONTH USING SUM(AMOUNT)::INTEGER)
----
INTEGER

View File

@@ -0,0 +1,63 @@
# name: test/sql/pivot/pivot_prepare.test
# description: Test preparing pivot statements
# group: [pivot]
statement ok
CREATE OR REPLACE TABLE monthly_sales(empid INT, amount INT, month TEXT);
statement ok
INSERT INTO monthly_sales VALUES
(1, 10000, '1-JAN'),
(1, 400, '1-JAN'),
(2, 4500, '1-JAN'),
(2, 35000, '1-JAN'),
(1, 5000, '2-FEB'),
(1, 3000, '2-FEB'),
(2, 200, '2-FEB'),
(2, 90500, '2-FEB'),
(1, 6000, '3-MAR'),
(1, 5000, '3-MAR'),
(2, 2500, '3-MAR'),
(2, 9500, '3-MAR'),
(1, 8000, '4-APR'),
(1, 10000, '4-APR'),
(2, 800, '4-APR'),
(2, 4500, '4-APR');
statement ok
PREPARE v1 AS SELECT *
FROM monthly_sales
PIVOT(SUM(amount + ?) FOR MONTH IN ('1-JAN', '2-FEB', '3-MAR', '4-APR'))
AS p
ORDER BY EMPID;
query IIIII
EXECUTE v1(0)
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
# expressions in pivot
query IIIII
EXECUTE v1(1)
----
1 10402 8002 11002 18002
2 39502 90702 12002 5302
# prepare top-level pivot stmt
statement ok
PREPARE v2 AS
PIVOT monthly_sales ON MONTH USING SUM(AMOUNT + ?)
query IIIII rowsort
EXECUTE v2(1)
----
1 10402 8002 11002 18002
2 39502 90702 12002 5302
# parameters within subquery of top-level pivot statement not supported
statement error
PREPARE v3 AS
PIVOT (SELECT empid, amount + ? AS amount, month FROM monthly_sales) ON MONTH USING SUM(AMOUNT)
----
cannot have parameters in their source

View File

@@ -0,0 +1,72 @@
# name: test/sql/pivot/pivot_storage.test
# description: Test storage of views with pivots
# group: [pivot]
# load the DB from disk
load __TEST_DIR__/pivot_storage.db
statement ok
PRAGMA enable_verification
statement ok
CREATE OR REPLACE TABLE monthly_sales(empid INT, amount INT, month TEXT);
statement ok
INSERT INTO monthly_sales VALUES
(1, 10000, 'JAN'),
(1, 400, 'JAN'),
(2, 4500, 'JAN'),
(2, 35000, 'JAN'),
(1, 5000, 'FEB'),
(1, 3000, 'FEB'),
(2, 200, 'FEB'),
(2, 90500, 'FEB'),
(1, 6000, 'MAR'),
(1, 5000, 'MAR'),
(2, 2500, 'MAR'),
(2, 9500, 'MAR'),
(1, 8000, 'APR'),
(1, 10000, 'APR'),
(2, 800, 'APR'),
(2, 4500, 'APR');
statement ok
CREATE VIEW v1 AS SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'APR'))
AS p
ORDER BY EMPID;
statement ok
CREATE MACRO pivot_macro(val)
as TABLE SELECT *
FROM monthly_sales
PIVOT(SUM(amount + val) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'APR'))
AS p
ORDER BY EMPID;
query IIIII
FROM v1;
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
query IIIII
FROM pivot_macro(1);
----
1 10402 8002 11002 18002
2 39502 90702 12002 5302
restart
query IIIII
FROM v1;
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
query IIIII
FROM pivot_macro(1);
----
1 10402 8002 11002 18002
2 39502 90702 12002 5302

View File

@@ -0,0 +1,23 @@
# name: test/sql/pivot/pivot_struct_aggregate.test
# description: Issue #12328: Segmentation fault during PIVOTING table (CLI) using struct field
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
create table donnees_csv as select {'year': i::varchar, 'month': i::varchar} AS donnee, i%5 as variable_id, i%10 id_niv from range(1000) t(i);
query IIIIII
pivot donnees_csv on variable_id using first(donnee) group by id_niv order by all;
----
0 {'year': 0, 'month': 0} NULL NULL NULL NULL
1 NULL {'year': 1, 'month': 1} NULL NULL NULL
2 NULL NULL {'year': 2, 'month': 2} NULL NULL
3 NULL NULL NULL {'year': 3, 'month': 3} NULL
4 NULL NULL NULL NULL {'year': 4, 'month': 4}
5 {'year': 5, 'month': 5} NULL NULL NULL NULL
6 NULL {'year': 6, 'month': 6} NULL NULL NULL
7 NULL NULL {'year': 7, 'month': 7} NULL NULL
8 NULL NULL NULL {'year': 8, 'month': 8} NULL
9 NULL NULL NULL NULL {'year': 9, 'month': 9}

View File

@@ -0,0 +1,54 @@
# name: test/sql/pivot/pivot_subquery.test
# description: Test pivot over subquery
# group: [pivot]
statement ok
PRAGMA enable_verification
# pivot using an enum
statement ok
CREATE OR REPLACE TABLE sales(empid INT, amount INT, d DATE);
statement ok
INSERT INTO sales VALUES
(1, 10000, DATE '2000-01-01'),
(1, 400, DATE '2000-01-07'),
(2, 4500, DATE '2001-01-21'),
(2, 35000, DATE '2001-01-21'),
(1, 5000, DATE '2000-02-03'),
(1, 3000, DATE '2000-02-07'),
(2, 200, DATE '2001-02-05'),
(2, 90500, DATE '2001-02-19'),
(1, 6000, DATE '2000-03-01'),
(1, 5000, DATE '2000-03-09'),
(2, 2500, DATE '2001-03-03'),
(2, 9500, DATE '2001-03-08');
# PIVOT over a subquery
query IIIIIII
PIVOT (SELECT YEAR(d) AS year, MONTH(d) AS month, empid, amount FROM sales) ON YEAR, MONTH USING SUM(AMOUNT) ORDER BY ALL;
----
1 10400 8000 11000 NULL NULL NULL
2 NULL NULL NULL 39500 90700 12000
# PIVOT over a PIVOT
query II
PIVOT (PIVOT (SELECT YEAR(d) AS year, MONTH(d) AS month, empid, amount FROM sales) ON YEAR, MONTH USING SUM(AMOUNT))
ON empid USING SUM(COALESCE("2000_1",0) + COALESCE("2000_2",0) + COALESCE("2000_3",0) + COALESCE("2001_1",0) + COALESCE("2001_2",0) + COALESCE("2001_3",0))
----
29400 142200
statement error
CREATE VIEW pivot_view AS PIVOT (SELECT YEAR(d) AS year, MONTH(d) AS month, empid, amount FROM sales) ON YEAR, MONTH USING SUM(AMOUNT);
----
cannot be used in views
statement error
CREATE MACRO xt2(a) as TABLE PIVOT sales ON d USING SUM(amount)
----
cannot be used in macros
statement error
CREATE MACRO xt2(a) as (PIVOT sales ON d USING SUM(amount))
----
cannot be used in macros

View File

@@ -0,0 +1,63 @@
# name: test/sql/pivot/pivot_tpch.test_slow
# description: Test pivot on the TPC-H dataset
# group: [pivot]
require tpch
statement ok
CALL dbgen(sf=0.1);
query IIIII
FROM (PIVOT lineitem ON l_shipinstruct USING SUM(l_quantity) GROUP BY l_returnflag) ORDER BY ALL;
----
A 943655 940094 946224 944227
N 1938403 1930781 1951198 1954697
R 950702 947111 937692 950018
query IIIII
SELECT * FROM lineitem PIVOT (SUM(l_quantity) FOR l_shipinstruct IN ('COLLECT COD', 'DELIVER IN PERSON', 'NONE', 'TAKE BACK RETURN') GROUP BY l_returnflag) ORDER BY ALL;
----
A 943655 940094 946224 944227
N 1938403 1930781 1951198 1954697
R 950702 947111 937692 950018
query IIIII
SELECT * FROM (SELECT l_shipinstruct, l_quantity, l_returnflag FROM lineitem) PIVOT (SUM(l_quantity) FOR l_shipinstruct IN ('COLLECT COD', 'DELIVER IN PERSON', 'NONE', 'TAKE BACK RETURN')) ORDER BY ALL;
----
A 943655 940094 946224 944227
N 1938403 1930781 1951198 1954697
R 950702 947111 937692 950018
query IIIIIIII
FROM (PIVOT (SELECT YEAR(l_shipdate) AS year, l_returnflag, l_quantity FROM lineitem) ON year USING SUM(l_quantity)) ORDER BY ALL
----
A 968197 1138593 1177788 489622 NULL NULL NULL
N NULL NULL NULL 1362746 2331027 2312320 1768986
R 984816 1143586 1170734 486387 NULL NULL NULL
query IIIIIIII
SELECT * FROM
(SELECT YEAR(l_shipdate) AS year, l_returnflag, l_quantity FROM lineitem)
PIVOT (SUM(l_quantity) FOR year IN (1992, 1993, 1994, 1995, 1996, 1997, 1998))
ORDER BY ALL
----
A 968197 1138593 1177788 489622 NULL NULL NULL
N NULL NULL NULL 1362746 2331027 2312320 1768986
R 984816 1143586 1170734 486387 NULL NULL NULL
# pivot TPC-H with order by
query IIIII
PIVOT lineitem ON l_quantity IN (SELECT l_quantity FROM (SELECT l_quantity, SUM(l_extendedprice) FROM lineitem GROUP BY ALL ORDER BY 2 DESC LIMIT 3)) USING SUM(l_extendedprice) GROUP BY l_returnflag, l_linestatus ORDER BY ALL
----
A F 209534220.50 206021055.17 195552797.28
N F 5063584.50 4429644.59 4883853.60
N O 417586267.50 416159447.06 405550037.76
R F 208093392.50 203387031.75 207333386.88
query IIIII
PIVOT lineitem ON l_quantity IN (SELECT l_quantity FROM (SELECT l_quantity, SUM(l_extendedprice) FROM lineitem GROUP BY ALL ORDER BY 2 LIMIT 3)) USING SUM(l_extendedprice) GROUP BY l_returnflag, l_linestatus ORDER BY ALL
----
A F 4271754.85 8199789.34 12264783.63
N F 130194.90 229144.78 281071.35
N O 8325866.03 16956521.54 25251628.56
R F 4181125.20 8312749.92 12666114.42

View File

@@ -0,0 +1,72 @@
# name: test/sql/pivot/test_multi_pivot.test
# description: Test pivoting over multiple dimensions
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE OR REPLACE TABLE sales(empid INT, amount INT, month TEXT, year INT);
statement ok
INSERT INTO sales VALUES
(1, 10000, 'JAN', 2020),
(1, 400, 'JAN', 2021),
(2, 4500, 'JAN', 2021),
(2, 35000, 'JAN', 2020),
(1, 5000, 'FEB', 2020),
(1, 3000, 'FEB', 2021),
(2, 200, 'FEB', 2021),
(2, 90500, 'FEB', 2020),
(1, 6000, 'MAR', 2021),
(1, 5000, 'MAR', 2021),
(2, 2500, 'MAR', 2021),
(2, 9500, 'MAR', 2021),
(1, 8000, 'APR', 2020),
(1, 10000, 'APR', 2020),
(2, 800, 'APR', 2021),
(2, 4500, 'APR', 2020);
query IIIIIIIII
SELECT *
FROM sales
PIVOT(
SUM(amount)
FOR YEAR IN (2020, 2021)
MONTH IN ('JAN', 'FEB', 'MAR', 'APR')
) AS p
ORDER BY EMPID;
----
1 10000 5000 NULL 18000 400 3000 11000 NULL
2 35000 90500 NULL 4500 4500 200 12000 800
query IIIIIIIII
SELECT *
FROM sales
PIVOT(
SUM(amount + year)
FOR YEAR IN (2020, 2021)
MONTH IN ('JAN', 'FEB', 'MAR', 'APR')
) AS p
ORDER BY EMPID;
----
1 12020 7020 NULL 22040 2421 5021 15042 NULL
2 37020 92520 NULL 6520 6521 2221 16042 2821
statement ok
SET pivot_limit=10000
# too many pivots
statement error
SELECT *
FROM sales
PIVOT(
SUM(amount)
FOR YEAR IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
MONTH IN ('JAN', 'FEB', 'MAR', 'APR')
amount IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
empid IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
) AS p
ORDER BY EMPID;
----
Pivot column limit of 10000 exceeded

View File

@@ -0,0 +1,293 @@
# name: test/sql/pivot/test_pivot.test
# description: Test standard SQL pivot syntax
# group: [pivot]
# example taken from SQL server docs
# https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE Product(DaysToManufacture int, StandardCost int);
statement ok
INSERT INTO Product VALUES (0, 5.0885), (1, 223.88), (2, 359.1082), (4, 949.4105);
query II rowsort
SELECT DaysToManufacture, AVG(StandardCost) AS AverageCost
FROM Product
GROUP BY DaysToManufacture;
----
0 5.0
1 224.0
2 359.0
4 949.0
query IIIIII
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days,
"0", "1", "2", "3", "4"
FROM
(
SELECT DaysToManufacture, StandardCost
FROM Product
) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN (0, 1, 2, 3, 4)
) AS PivotTable;
----
AverageCost 5.0 224.0 359.0 NULL 949.0
# example taken from the snowflake docs
# https://docs.snowflake.com/en/sql-reference/constructs/pivot
statement ok
CREATE OR REPLACE TABLE monthly_sales(empid INT, amount INT, month TEXT);
statement ok
INSERT INTO monthly_sales VALUES
(1, 10000, 'JAN'),
(1, 400, 'JAN'),
(2, 4500, 'JAN'),
(2, 35000, 'JAN'),
(1, 5000, 'FEB'),
(1, 3000, 'FEB'),
(2, 200, 'FEB'),
(2, 90500, 'FEB'),
(1, 6000, 'MAR'),
(1, 5000, 'MAR'),
(2, 2500, 'MAR'),
(2, 9500, 'MAR'),
(1, 8000, 'APR'),
(1, 10000, 'APR'),
(2, 800, 'APR'),
(2, 4500, 'APR');
query IIIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'APR'))
AS p
ORDER BY EMPID;
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
# expressions in pivot
query IIIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount+1) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'DEC'))
AS p
ORDER BY EMPID;
----
1 10402 8002 11002 NULL
2 39502 90702 12002 NULL
# count star
query IIIII
SELECT *
FROM monthly_sales
PIVOT(COUNT(*) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'DEC') GROUP BY empid)
AS p
ORDER BY EMPID;
----
1 2 2 2 0
2 2 2 2 0
# test pivot aliases
query IIIII
SELECT empid, January, February, March, April
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('JAN' AS January, 'FEB' AS February, 'MAR' AS March, 'APR' AS April))
AS p
ORDER BY EMPID;
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
# not all columns are mentioned (columns not mentioned are dropped)
query IIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('JAN', 'FEB', 'MAR'))
AS p
ORDER BY EMPID;
----
1 10400 8000 11000
2 39500 90700 12000
# extra columns that don't occur in the data -> they stay as NULL
query IIIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'DEC'))
AS p
ORDER BY EMPID;
----
1 10400 8000 11000 NULL
2 39500 90700 12000 NULL
# aliases
query IIIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'APR'))
AS p (EMP_ID_renamed, JAN, FEB, MAR, APR)
ORDER BY EMP_ID_renamed;
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
# NULL pivot
statement ok
INSERT INTO monthly_sales VALUES (1, 250, NULL);
query IIIIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN (NULL, 'JAN', 'FEB', 'MAR', 'APR'))
AS p
ORDER BY EMPID;
----
1 250 10400 8000 11000 18000
2 NULL 39500 90700 12000 5300
query III
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN (NULL, 'JAN', 'FEB', 'MAR', 'APR'))
AS p
UNPIVOT INCLUDE NULLS(amount FOR MONTH IN ("NULL", JAN, FEB, MAR, APR))
ORDER BY ALL;
----
1 APR 18000
1 FEB 8000
1 JAN 10400
1 MAR 11000
1 NULL 250
2 APR 5300
2 FEB 90700
2 JAN 39500
2 MAR 12000
2 NULL NULL
query III
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN (NULL, 'JAN', 'FEB', 'MAR', 'APR'))
AS p
UNPIVOT EXCLUDE NULLS(amount FOR MONTH IN ("NULL", JAN, FEB, MAR, APR))
ORDER BY ALL;
----
1 APR 18000
1 FEB 8000
1 JAN 10400
1 MAR 11000
1 NULL 250
2 APR 5300
2 FEB 90700
2 JAN 39500
2 MAR 12000
query III
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN (NULL, 'JAN', 'FEB', 'MAR', 'APR'))
AS p
UNPIVOT EXCLUDE NULLS(amount FOR MONTH IN ("NULL", JAN, FEB, MAR, APR))
ORDER BY EMPID;
----
1 NULL 250
1 JAN 10400
1 FEB 8000
1 MAR 11000
1 APR 18000
2 JAN 39500
2 FEB 90700
2 MAR 12000
2 APR 5300
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('JAN', 'JAN'))
AS p
ORDER BY EMPID;
----
was specified multiple times
# cannot use non-aggregate functions
statement error
SELECT *
FROM monthly_sales
PIVOT(COS(amount) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'APR'))
AS p (EMP_ID_renamed, JAN, FEB, MAR, APR)
ORDER BY EMP_ID_renamed;
----
# subqueries not allowed
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount + (SELECT 42)) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'APR'))
AS p (EMP_ID_renamed, JAN, FEB, MAR, APR)
ORDER BY EMP_ID_renamed;
----
cannot contain subqueries
# window functions not allowed
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount + row_number() over ()) FOR MONTH IN ('JAN', 'FEB', 'MAR', 'APR'))
AS p (EMP_ID_renamed, JAN, FEB, MAR, APR)
ORDER BY EMP_ID_renamed;
----
cannot contain window functions
# unrecognized IN clause
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTHx IN ('JAN', 'FEB', 'MAR', 'DEC'))
AS p
ORDER BY EMPID;
----
MONTHx
# empty IN clause
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ())
AS p
ORDER BY EMPID;
----
Parser Error: syntax error at or near ")"
# star
statement error
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN (*))
AS p
ORDER BY EMPID;
----
Parser Error: PIVOT IN list must contain columns or lists of columns
query I
FROM
(
SELECT DaysToManufacture, StandardCost
FROM Product
) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN ('zz')
) AS PivotTable;
----
NULL

View File

@@ -0,0 +1,182 @@
# 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

View File

@@ -0,0 +1,98 @@
# name: test/sql/pivot/test_unpivot_stmt.test
# description: Test unpivot of the stack-overflow example - https://stackoverflow.com/questions/72922418/create-rows-from-part-of-column-names/72939299
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE t1(id BIGINT, "Sales (05/19/2020)" BIGINT, "Sales (06/03/2020)" BIGINT, "Sales (10/23/2020)" BIGINT);
statement ok
INSERT INTO t1 VALUES(10629465, 23, 47, 99);
statement ok
INSERT INTO t1 VALUES(98765432, 10, 99, 33);
# SQL standard syntax
query III
SELECT id, regexp_replace(date, 'Sales [(]([0-9]+)/([0-9]+)/([0-9]+)[)]', '\3-\1-\2')::DATE AS date, sales
FROM t1
UNPIVOT (sales FOR date IN ("Sales (05/19/2020)", "Sales (06/03/2020)", "Sales (10/23/2020)"))
ORDER BY ALL;
----
10629465 2020-05-19 23
10629465 2020-06-03 47
10629465 2020-10-23 99
98765432 2020-05-19 10
98765432 2020-06-03 99
98765432 2020-10-23 33
# base unpivot statement
query III
SELECT id, regexp_replace(date, 'Sales [(]([0-9]+)/([0-9]+)/([0-9]+)[)]', '\3-\1-\2')::DATE AS date, sales
FROM
(UNPIVOT t1 ON "Sales (05/19/2020)", "Sales (06/03/2020)", "Sales (10/23/2020)" INTO NAME date VALUE sales)
ORDER BY ALL;
----
10629465 2020-05-19 23
10629465 2020-06-03 47
10629465 2020-10-23 99
98765432 2020-05-19 10
98765432 2020-06-03 99
98765432 2020-10-23 33
# alias
query III
SELECT *
FROM
(UNPIVOT t1 ON "Sales (05/19/2020)" AS "2020-05-19", "Sales (06/03/2020)" AS "2020-06-03", "Sales (10/23/2020)" AS "2020-10-23" INTO NAME date VALUE sales)
ORDER BY ALL;
----
10629465 2020-05-19 23
10629465 2020-06-03 47
10629465 2020-10-23 99
98765432 2020-05-19 10
98765432 2020-06-03 99
98765432 2020-10-23 33
# regex in UNPIVOT
query III
SELECT id, regexp_replace(date, 'Sales [(]([0-9]+)/([0-9]+)/([0-9]+)[)]', '\3-\1-\2')::DATE AS date, sales FROM t1
UNPIVOT (Sales FOR Date IN (COLUMNS('Sales.*')))
ORDER BY ALL;
----
10629465 2020-05-19 23
10629465 2020-06-03 47
10629465 2020-10-23 99
98765432 2020-05-19 10
98765432 2020-06-03 99
98765432 2020-10-23 33
# UNPIVOT statement
query III
SELECT id, regexp_replace(date, 'Sales [(]([0-9]+)/([0-9]+)/([0-9]+)[)]', '\3-\1-\2')::DATE AS date, sales
FROM
(UNPIVOT t1 ON COLUMNS('Sales.*') INTO NAME date VALUE sales)
ORDER BY ALL;
----
10629465 2020-05-19 23
10629465 2020-06-03 47
10629465 2020-10-23 99
98765432 2020-05-19 10
98765432 2020-06-03 99
98765432 2020-10-23 33
# exclude clause
query III
SELECT id, regexp_replace(date, 'Sales [(]([0-9]+)/([0-9]+)/([0-9]+)[)]', '\3-\1-\2')::DATE AS date, sales
FROM
(UNPIVOT t1 ON * EXCLUDE (id) INTO NAME date VALUE sales)
ORDER BY ALL;
----
10629465 2020-05-19 23
10629465 2020-06-03 47
10629465 2020-10-23 99
98765432 2020-05-19 10
98765432 2020-06-03 99
98765432 2020-10-23 33

View File

@@ -0,0 +1,135 @@
# name: test/sql/pivot/top_level_pivot_syntax.test
# description: Test top-level pivot syntax
# group: [pivot]
statement ok
PRAGMA enable_verification
# pivot using an enum
statement ok
CREATE OR REPLACE TABLE monthly_sales(empid INT, amount INT, month TEXT);
statement ok
INSERT INTO monthly_sales VALUES
(1, 10000, '1-JAN'),
(1, 400, '1-JAN'),
(2, 4500, '1-JAN'),
(2, 35000, '1-JAN'),
(1, 5000, '2-FEB'),
(1, 3000, '2-FEB'),
(2, 200, '2-FEB'),
(2, 90500, '2-FEB'),
(1, 6000, '3-MAR'),
(1, 5000, '3-MAR'),
(2, 2500, '3-MAR'),
(2, 9500, '3-MAR'),
(1, 8000, '4-APR'),
(1, 10000, '4-APR'),
(2, 800, '4-APR'),
(2, 4500, '4-APR');
# top level PIVOT syntax
query IIIII rowsort
PIVOT monthly_sales ON MONTH USING SUM(AMOUNT)
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
query IIIII rowsort
FROM (PIVOT monthly_sales ON MONTH USING SUM(AMOUNT));
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
query IIIII rowsort
PIVOT monthly_sales ON MONTH USING SUM(AMOUNT) GROUP BY empid
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
query IIIII rowsort
PIVOT monthly_sales ON MONTH IN ('1-JAN', '2-FEB', '3-MAR', '4-APR') USING SUM(AMOUNT) GROUP BY empid
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
query IIII rowsort
PIVOT monthly_sales ON MONTH IN ('1-JAN', '2-FEB', '3-MAR') USING SUM(AMOUNT) GROUP BY empid
----
1 10400 8000 11000
2 39500 90700 12000
query IIIII rowsort
PIVOT monthly_sales ON MONTH USING SUM(AMOUNT) GROUP BY empid
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
# add a column
statement ok
ALTER TABLE monthly_sales ADD COLUMN status VARCHAR
statement ok
UPDATE monthly_sales SET status=CASE WHEN amount >= 10000 THEN 'important' ELSE 'regular' END
# test the ROWS syntax
query IIIIII
FROM (PIVOT monthly_sales ON MONTH USING SUM(AMOUNT)) ORDER BY ALL;
----
1 important 10000 NULL NULL 10000
1 regular 400 8000 11000 8000
2 important 35000 90500 NULL NULL
2 regular 4500 200 12000 5300
query IIIII
PIVOT monthly_sales ON MONTH USING SUM(AMOUNT) GROUP BY empid ORDER BY ALL
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300
query IIIII
FROM (PIVOT monthly_sales ON MONTH USING SUM(AMOUNT) GROUP BY status) ORDER BY ALL
----
important 45000 90500 NULL 10000
regular 4900 8200 23000 13300
# GROUP BY syntax in the SQL standard PIVOT clause
query IIIII
SELECT *
FROM monthly_sales
PIVOT(SUM(amount) FOR MONTH IN ('1-JAN', '2-FEB', '3-MAR', '4-APR') GROUP BY status)
AS p
ORDER BY 1;
----
important 45000 90500 NULL 10000
regular 4900 8200 23000 13300
# in CTE
query IIIII
WITH pivoted_sales AS (PIVOT monthly_sales ON MONTH USING SUM(AMOUNT) GROUP BY empid)
SELECT * FROM pivoted_sales ORDER BY empid DESC;
----
2 39500 90700 12000 5300
1 10400 8000 11000 18000
# in CTE
query IIIII
WITH pivoted_sales AS MATERIALIZED (PIVOT monthly_sales ON MONTH USING SUM(AMOUNT) GROUP BY empid)
SELECT * FROM pivoted_sales ORDER BY empid DESC;
----
2 39500 90700 12000 5300
1 10400 8000 11000 18000
statement error
CREATE VIEW v1 AS PIVOT monthly_sales ON MONTH USING SUM(AMOUNT)
----
PIVOT ... ON "MONTH" IN (val1, val2, ...)
statement ok
CREATE VIEW v1 AS PIVOT monthly_sales ON MONTH IN ('1-JAN', '2-FEB', '3-MAR', '4-APR') USING SUM(AMOUNT) GROUP BY empid ORDER BY ALL
query IIIII
FROM v1
----
1 10400 8000 11000 18000
2 39500 90700 12000 5300

View File

@@ -0,0 +1,65 @@
# name: test/sql/pivot/unpivot_expression.test
# description: Test expressions in UNPIVOT
# group: [pivot]
statement ok
PRAGMA enable_verification
query II
unpivot (select 42 as col1, 'woot' as col2)
on col1::VARCHAR, col2;
----
col1 42
col2 woot
query II
unpivot (select 42 as col1, 'woot' as col2)
on COLUMNS(*)::VARCHAR;
----
col1 42
col2 woot
query II
unpivot (select 42 as col1, 'woot' as col2)
on (col1 + 100)::VARCHAR, col2;
----
col1 142
col2 woot
query II
unpivot (select 42 as col1, 'woot' as col2)
on (col1 + 100)::VARCHAR AS c, col2;
----
c 142
col2 woot
query II
select * from (select 42 as col1, 'woot' as col2) UNPIVOT ("value" FOR "name" IN (col1::VARCHAR, col2))
----
col1 42
col2 woot
# subqueries
statement error
unpivot (select 42 as col1, 'woot' as col2)
on (col1 + (SELECT col1))::VARCHAR, col2;
----
<REGEX>:.*Binder Error.*UNPIVOT list cannot contain subqueries.*
statement error
unpivot (select 42 as col1, 'woot' as col2)
on random(), col2;
----
<REGEX>:.*Binder Error.*UNPIVOT clause must contain exactly one column.*
statement error
unpivot (select 42 as col1, 'woot' as col2)
on col1 + col2;
----
<REGEX>:.*Binder Error.*UNPIVOT clause must contain exactly one column.*
statement error
unpivot (select 42 as col1, 'woot' as col2)
on t.col1::VARCHAR, col2;
----
<REGEX>:.*Binder Error.*not found.*

View File

@@ -0,0 +1,19 @@
# name: test/sql/pivot/unpivot_internal_names.test
# description: Test unpivoting on a table with names used internally by the unpivot operator
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE unpivot_names(unpivot_names VARCHAR, unpivot_list VARCHAR, unpivot_list_2 VARCHAR, col1 INT, col2 INT, col3 INT);
statement ok
INSERT INTO unpivot_names VALUES ('unpivot_names', 'unpivot_list', 'unpivot_list_2', 1, 2, 3);
query IIIII
UNPIVOT unpivot_names ON COLUMNS('col*')
----
unpivot_names unpivot_list unpivot_list_2 col1 1
unpivot_names unpivot_list unpivot_list_2 col2 2
unpivot_names unpivot_list unpivot_list_2 col3 3

View File

@@ -0,0 +1,14 @@
# name: test/sql/pivot/unpivot_no_columns.test
# description: Test UNPIVOT without columns
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
create table integers(i integer);
statement error
unpivot integers on columns(* exclude (i));
----
UNPIVOT clause must unpivot on at least one column

View File

@@ -0,0 +1,35 @@
# name: test/sql/pivot/unpivot_non_aligned_columns.test
# description: Test unpivot with unaligned columns
# group: [pivot]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE test(id BIGINT, metric_1 VARCHAR, value_x VARCHAR, metric_2 VARCHAR, value_q VARCHAR, metric_3 VARCHAR, value_j VARCHAR);;
statement ok
INSERT INTO test VALUES(1,'a','a_value','b','b_value','c','c_value');
statement ok
INSERT INTO test VALUES(2,'d','d_value','e','e_value','f','f_value');
statement error
UNPIVOT test ON (metric_1, value_x), metric_2, metric_3;
----
UNPIVOT value count mismatch
statement error
UNPIVOT test ON (metric_1, value_x), (metric_2, value_q), (metric_3, value_j) INTO NAME metric VALUE metric_value;
----
UNPIVOT name count mismatch
query IIII
UNPIVOT test ON (metric_1, value_x), (metric_2, value_q), (metric_3, value_j) INTO NAME metric VALUES metric_value, metric_type;
----
1 metric_1_value_x a a_value
1 metric_2_value_q b b_value
1 metric_3_value_j c c_value
2 metric_1_value_x d d_value
2 metric_2_value_q e e_value
2 metric_3_value_j f f_value

View File

@@ -0,0 +1,18 @@
# name: test/sql/pivot/unpivot_types.test
# description: Test return types of UNPIVOT statement
# group: [pivot]
statement ok
PRAGMA enable_verification
query II
SELECT column_name, column_type FROM (DESCRIBE unpivot ( select 42) on columns(*))
----
name VARCHAR
value INTEGER
query II
SELECT column_name, column_type FROM (DESCRIBE unpivot ( select {n : 1 }) on columns(*))
----
name VARCHAR
value STRUCT(n INTEGER)

View File

@@ -0,0 +1,13 @@
# name: test/sql/pivot/unpivot_unnamed_subquery.test
# description: Test top-level pivot syntax
# group: [pivot]
statement ok
PRAGMA enable_verification
query II
unpivot (select cast(columns(*) as varchar) from (select 42 as col1, 'woot' as col2))
on columns(*);
----
col1 42
col2 woot