The correct Postgres syntax would be:
SELECT * FROM (VALUES (1)) AS q (col1);
A set of parentheses was missing.
But Redshift does not support free-standing VALUES expressions (outside of INSERT commands). So, for a single row:
SELECT * FROM (SELECT 1) AS q (col1);
For multiple rows (without using UNION ALL like requested) you can use a temporary table:
CREATE TEMP TABLE q(col1 int);
INSERT INTO q(col1)
VALUES (1), (2), (3);
SELECT * FROM q;
The manual:
A temporary table is automatically dropped at the end of the session in which it was created.
If UNION ALL is an option:
SELECT 1 AS col1
UNION ALL SELECT 2
UNION ALL SELECT 3;
Answer from Erwin Brandstetter on Stack OverflowVideos
unfortunately UNION is the only way here:
WITH bar (baz) AS
(select 'a' union select 'b' union select 'c')
SELECT * from bar;
TLDR: The most efficient way to simulate a multi-row VALUES clause is to create an array-of-arrays for the rows and columns of the data, and then unpack it and (if necessary) cast to the desired data types:
select rowdata[0]::varchar, rowdata[1]::decimal
from
(select array(
array('a', 1),
array('b', 2)
) as arr) as data,
data.arr as rowdata
(The data.arr as rowdata bit is to unnest the array.)
UNION ALL has the unfortunate behavior that each of the SELECT statements will be distributed across the cluster:
explain select * from (select 'a' union all select 'b' union all select 'c')
XN Subquery Scan derived_table1 (cost=0.00..0.09 rows=3 width=32)
-> XN Append (cost=0.00..0.06 rows=3 width=0)
-> XN Network (cost=0.00..0.02 rows=1 width=0)
Distribute Round Robin
-> XN Subquery Scan "*SELECT* 1" (cost=0.00..0.02 rows=1 width=0)
-> XN Result (cost=0.00..0.01 rows=1 width=0)
-> XN Network (cost=0.00..0.02 rows=1 width=0)
Distribute Round Robin
-> XN Subquery Scan "*SELECT* 2" (cost=0.00..0.02 rows=1 width=0)
-> XN Result (cost=0.00..0.01 rows=1 width=0)
-> XN Network (cost=0.00..0.02 rows=1 width=0)
Distribute Round Robin
-> XN Subquery Scan "*SELECT* 3" (cost=0.00..0.02 rows=1 width=0)
-> XN Result (cost=0.00..0.01 rows=1 width=0)
On more than a few rows, this incurs an absurd overhead and makes queries extremely inefficient. Fortunately, we can use the SUPER data type as a workaround; when we select a single value (the array-of-arrays) the query planner sees this as a single query which it only needs to distribute to one node, which is much more efficient to execute.
Redshift does have the ability to do this, though it's hidden in the docs. You can use a session context variable that lasts as long as the session in which it was created. The naming convention has to be a two-part name separated by a dot (ex: identifier.identifier). Details are buried in the SET and the CURRENT_SETTING documentation.
Here's an example:
SET context.my_variable TO 89;
SELECT * FROM table WHERE id = CURRENT_SETTING('context.my_variable')
Redshift does not support variables. If your use case is that you want to use one particular value in multiple subqueries, the easiest option is to use a Common Table Expression such as
with myvariables as (
SELECT '2023-02-21'::DATE AS TargetDate
)
select *
from mytable
where targetdate = (select TargetDate from myvariables)
See also Declare a variable in RedShift