The following query works in Postgresql but not in Redshift:
WITH bar (baz) AS
(VALUES ('a'), ('b'), ('c'))
SELECT * from bar;
Which gives
baz
---
a
b
c
How can I replicate this behaviour in Redshift?
unfortunately UNION is the only way here:
WITH bar (baz) AS
(select 'a' union select 'b' union select 'c')
SELECT * from bar;
this is also a good option, IF you do NOT want to use 'WITH' option.
select C1, C2, C3 from
(select '2021-10-01' as C1 , '2021-12-31' as C2 , 'Q4' as c3
union all
select '2021-01-01' , '2021-03-31' , 'Q1'
)
Related
Is it possible to return multiple column on single CASE evaluation in DB2?
below query return single column.
select (case when 1=1 then 0 else 1 end) as col from table;
I need multiple column like
select (case when 1=1 then 0 as col, 1 as col1 else 2 as col1 , 3 as col2 end) from table;
select (case when 1=1 then 0,1 else 2, 3 end)col , col1 from table;
Is coalesce function is use full for above conditions? thanks.
It’s not possible with a single CASE statement in Db2.
But you may use something like below.
select
coalesce(t1.c1, t2.c1, t3.c1) c1
, coalesce(t1.c2, t2.c2, t3.c2) c2
from
(
select tabschema, tabname, rownumber() over (partition by tabschema) rn_
from syscat.tables
) b
left join table(values ('_SYSIBM_', b.tabname)) t1 (c1, c2) on b.tabschema='SYSIBM'
left join table(values ('_SYSCAT_', b.tabname)) t2 (c1, c2) on b.tabschema='SYSCAT'
cross join table(values (b.tabschema, b.tabname)) t3 (c1, c2)
where b.rn_=1;
The sub-select on syscat.tables is constructed to return only one table from each schema just to show the idea (your base table must be there instead of it). "Case condition" here is what you see in the on clause of each join. "Returned values" of this "Case expression" are inside the values clauses.
A CASE statement can be re-written as a UNION. Logically they are the same thing.
So, you could do this
select 0 as col, 1 as col1 from table where 1=1
UNION ALL
select 2 as col, 3 as col1 from table where NOT 1=1 OR 1=1 IS NULL
I'm trying to join a sub query but as the table contains no unique row_id and I need the most recent record of a specific type, I want to do an Order by Date Desc and get the Top 1 from that, but it doesn't seem allowed in Sybase ASE.
I put together a small sample to show kinda what i'm trying to do.
CREATE TABLE #test_users (USER_ID CHAR(9), USER_CK INT)
INSERT INTO #test_users (USER_ID, USER_CK)
SELECT 'QA0000001', 123000010
UNION ALL SELECT 'QA0000002', 123000020
UNION ALL SELECT 'QA0000003', 123000030
UNION ALL SELECT 'QA0000004', 123000040
UNION ALL SELECT 'QA0000005', 123000050
CREATE TABLE #test_records (STAT_TYPE CHAR(3), USER_CK INT, MOD_DT DATE, PLAN_ID CHAR(1))
INSERT INTO #test_records (STAT_TYPE, USER_CK, MOD_DT, PLAN_ID)
SELECT 'ADD', 123000010, '8/1/2017', 'A'
UNION ALL SELECT 'TRM', 123000010, '6/1/2018', 'A'
UNION ALL SELECT 'ADD', 123000010, '6/1/2018', 'B'
UNION ALL SELECT 'ADD', 123000020, '5/1/2017', 'A'
UNION ALL SELECT 'TRM', 123000020, '9/1/2018', 'A'
UNION ALL SELECT 'ADD', 123000030, '3/1/2018', 'A'
UNION ALL SELECT 'ADD', 123000040, '4/1/2018', 'A'
UNION ALL SELECT 'ADD', 123000050, '1/1/2018', 'B'
UNION ALL SELECT 'TRM', 123000050, '7/1/2018', 'B'
UNION ALL SELECT 'ADD', 123000050, '7/1/2018', 'A'
--Want to know everyone that has ever been in Plan A, and what their last status type was.
--Should return
-- QA0000001, A, TRM, 6/1/2018
-- QA0000002, A, TRM, 9/1/2018
-- QA0000003, A, ADD, 3/1/2018
-- QA0000004, A, ADD, 4/1/2018
-- QA0000005, A, ADD, 7/1/2018
SELECT u.USER_ID, r.PLAN_ID, r.STAT_TYPE, r.MOD_DT FROM #test_users u
LEFT JOIN #test_records r
ON PLAN_ID = 'A'
AND u.USER_CK = r.USER_CK
Thanks for any help you could provide.
Mike
I have a query like this, and appearantly Impala doesn't support subqueries in SELECT statement. How can I neatly rewrite it in Impala?
SELECT
col1,
col2,
...
CASE
WHEN (SELECT 1
FROM
table1 x,
table2 y
WHERE
x.id = y.id
LIMIT 1) = 1
THEN
'A'
ELSE
'B'
END
coln
FROM
...
Your query has the following error(s):
AnalysisException: Subqueries are not supported in the select list.
You could try
SELECT col1, col2, ... 'A' coln
FROM ...
WHERE EXISTS (SELECT 1 FROM table1 x, table2 y WHERE x.id = y.id LIMIT 1)
UNION ALL
SELECT col1, col2, ... 'B' coln
FROM ...
WHERE NOT EXISTS (SELECT 1 FROM table1 x, table2 y WHERE x.id = y.id LIMIT 1)
No guarantees, haven't tried it myself.
In general, a cleaner solution is placing the subqueries into the FROM clause, thereby linking the subqueries to the main table through inner or left joins. I usually do this when dealing with complex types in Impala.
However, in your specific example you are trying to do a left join, defining a field for each row which indicates whether the join was successful ('A') or not ('B'). In this case you could do the following:
SELECT
x.id, x.col2, x.col3, ...
CASE
WHEN y.id IS NOT NULL THEN 'A'
ELSE 'B'
END
coln
FROM table1 x LEFT JOIN
table2 y USING (id)
...
I'll try to create a query where the result can be from two different tables depending on the size of the first table.
Is something comparable even possible?
SELECT
CASE WHEN COUNT(table1.column1) > 5
THEN
column1,
column2,
column3
FROM table1
ELSE
column1,
column2,
column3
FROM table2
END
With this code I got something like this:
ERROR: syntax error at or near ","
LINE 4: column1,
with c (c) as (select count(c1) from t)
select c1, c2, c3
from t
where (select c from c) > 5
union all
select c1, c2, c3
from r
where (select c from c) <= 5
The corresponding columns must be of the same type. Or be casted to the same type.
WITH clause
UNION clause
Suppose that I have this query:
select *
from myTable
where myTable.myCol in (1,2,3)
I would like to do that:
with allowed_values as (1,2,3)
select *
from myTable
where myTable.myCol in allowed_values
It gives me a Syntax Error in the first row, can you help me fixing it?
The closest I can think to your syntax:
WITH allowed_values (id) AS
( VALUES
(1), (2), (3)
)
SELECT *
FROM myTable
WHERE id IN
(TABLE allowed_values) ;
Tested in SQL-Fiddle
Close to what you probably had in mind:
WITH allowed_values AS (SELECT '{1,2,3}'::int[] AS arr)
SELECT *
FROM my_table
,allowed_values -- cross join with a single row
WHERE my_col = ANY (arr);
Better:
WITH allowed_values (my_col) AS (VALUES (1), (2), (3))
SELECT *
FROM allowed_values
JOIN my_table USING (my_col)
But really, you can just simplify:
SELECT *
FROM (VALUES (1), (2), (3)) AS allowed_values (my_col)
JOIN my_table USING (my_col);
Try
with allowed_values as (select 1 as tst union all select 2 union all select 3)
select * from myTable a
inner join c1 b ON (b.tst = a.myCol)
The simplest way forward is to correct your common table expression, then use it in a subselect.
with allowed_values as (
select 1 id
union all
select 2
union all
select 3
)
select * from myTable
where myTable.id in (select id from allowed_values)