create implicit data without having to create temp/volatile/working table - sql

This is possible:
SELECT 'Bla' AS X
why is this not possible in TeraData:
SELECT 'Bla' AS X
UNION
SELECT 'DiBla' AS X
Is there a way to achieve the above without having to create a temp/volatile/working table in TeraData?
PS:
The error is: A select for a union, intersect or minus must reference a table

If you want two columns on one row, then use:
SELECT 'Bla' AS X, 'DiBla' AS Y
If you want:
X
Bla
DiBla
Then you just do:
select 'Bla' as X
union all
select 'DiBlah' as X;
If you want:
X Y
Bla NULL
NULL DiBla
Then:
SELECT 'Bla' as X, NULL as Y
UNION ALL
SELECT NULL as X, 'DiBla' as Y

You have a attribute name mishmash in your UNION. You can not perform UNION between relations having different structure. Therefore, use
SELECT cast('Bla' as varchar(6)) AS X FROM (SELECT 1 a) t
UNION
SELECT cast('DiBla' as varchar(6)) AS X FROM (SELECT 1 a) t
the explicit casting make sure that the data types are equivalent as well as the attribute names. Another solution could be
SELECT * FROM
(
SELECT cast('Bla' as varchar(6)) AS X
) t
UNION
SELECT * FROM
(
SELECT cast('DiBla' as varchar(6)) AS X
) t

Related

Converting error when try to UNION ALL temporary tables in SQL

I created a few temporary tables which I need to union using UNION ALL. This is how it looks in my code:
SELECT X, Y, Z
INTO #Tab1
FROM dbo.Cust
SELECT X, Y, Z
INTO #Tab2
FROM dbo.Cars
SELECT X, Y, Z
INTO #Tab3
FROM dbo.Colors
SELECT * FROM #Tab1
UNION ALL
SELECT * FROM #Tab2
UNION ALL
SELECT * FROM #Tab3
Unfortunately, I got an error:
Conversion failed when converting the nvarchar value .. to data type
int
However, when I try to union these tables but not as temporary ones, then no error arises. So, the solution below works fine and output is returned properly:
SELECT X, Y, Z
FROM dbo.Cust
UNION ALL
SELECT X, Y, Z
FROM dbo.Cars
UNION ALL
SELECT X, Y, Z
FROM dbo.Colors
Columns X, Y, Z are of the same type as in temp table. I guess there must be an issue with temp tables but don't know what exactly. Where is the problem and why it happens?

PostgreSQL union a variable of type array to the result set of a query

Is it possible to union a to union a variable to a select statement in PostgreSQL? I have a recursive function at the moment that in essence does this:
create or replace function call_recurrsive_function(ids bigint[])
.
.
select id from x where y
union call_recurrsive_function(select id from x where y)
.
I've recently made some changes that increase the complexity of the select by a lot, and to increase performance I'd like to run that query only once per function call and do something like
var = select id from x where y
union call_recurrsive_function(var)
You can try using a CTE (Common Table Expression). For example:
with
r as (
select id from x where y
)
select *
from (
select id from r
union call_recurrsive_function(select id from r)
) x

INTERSECT ALL not working on PostgreSQL 11

The PostgreSQL operation INTERSECT ALL does not seem to work. What am I missing?
The following query returns just one row containing the value two, but I am expecting two with the value as I am using intersect all.
(
(select 1 as z)
union all
(select 2 as z)
union all
(select 2 as z)
)
intersect all
(select 2 as z)
Does anyone have a guess?
There is only one row (with a value of 2 for the column z) in the second operand to INTERSECT ALL so only that one can be used to find a matching partner in the other operand.
Add a second row to the second operand of the INTERSECT ALL and you'll have two rows in the result.
(SELECT 1 z
UNION ALL
SELECT 2 z
UNION ALL
SELECT 2 z)
INTERSECT ALL
(SELECT 2 z
UNION ALL
SELECT 2 z);
Or you might instead want a join.
SELECT *
FROM (SELECT 1 z
UNION ALL
SELECT 2 z
UNION ALL
SELECT 2 z) x1
INNER JOIN (SELECT 2 z) x2
ON x2.z = x1.z;
This is how it works in all version, not just 11.
The single value of '2' on the right side of the INTERSECT ALL is consumed upon matching, and can't match multiple times.
Do you really want WHERE EXISTS (..) instead?

view key value rows as multi column single row

You have parameters x,y,z stored as key values.
You want to execute an expression z=x+y on those parameters. Expression is stored in another table.
You want to generate an SQL query as simply as possible from the expression.
How can you view those parameter values as a single row with columns (x,y,z) to enable execution of the expression ?
SELECT *
INTO #key_values
FROM
(
SELECT 'x' AS mykey, 2 AS myvalue
UNION ALL
SELECT 'y', 5
UNION ALL
SELECT 'z', 0
) a;
This screams for a PIVOT operator:
;WITH Inputs AS
(
SELECT 'x' AS mykey, 2 AS myvalue
UNION ALL
SELECT 'y', 5
UNION ALL
SELECT 'z', 0
)
SELECT
U.x,
U.y,
U.z,
Result = U.x + U.y
FROM
Inputs AS I
PIVOT (
MAX(I.myvalue) FOR I.mykey IN (x, y, z)
) AS U
Results:
x y z Result
2 5 0 7
You can build any expression you want with the pivoted columns in the SELECT.
If you want to update the z record, you will have to join back to the underlying table since after applying the PIVOT you lose access to original table.
IF OBJECT_ID('tempdb..#Input') IS NOT NULL
DROP TABLE #Input
CREATE TABLE #Input (
mykey VARCHAR(10),
myvalue INT)
INSERT INTO #Input (
mykey,
myvalue)
VALUES
('x', 2),
('y', 5),
('z', 0)
UPDATE I SET
myvalue = R.Result
FROM
#Input AS I
CROSS APPLY (
SELECT
Result = x + y
FROM
#Input AS I
PIVOT (MAX(I.myvalue) FOR I.mykey IN (x, y, z)) AS U
) AS R
WHERE
I.mykey = 'z'
Turn the 3 rows into a single 3 column row using a common table expression and update it to run the expression. So the proposed solution is an updatable cte.
WITH myvalues(x,y,z) AS (
SELECT x.myvalue, y.myvalue, z.myvalue
FROM #key_values AS x
JOIN #key_values AS y ON y.mykey='y' AND x.mykey='x'
JOIN #key_values AS z ON z.mykey='z'
)
UPDATE myvalues SET z=x+y;
SELECT myvalue FROM #key_values WHERE mykey='z';

Double IN Statements in SQL

Just curious about the IN statement in SQL.
I know I can search multiple columns with one value by doing
'val1' IN (col1,col2)
And can search a column for multiple values
col1 IN ('val1','val2')
But is there a way to do both of these simultaneously, without restorting to an repeating AND / OR in the SQl? I am looking to do this in the most scalable way, so independent of how many vals / cols i need to search in.
So essentially:
('val1','val2') IN (col1,col2)
but valid.
You could do something like this (which I've also put on SQLFiddle):
-- Test data:
WITH t(col1, col2) AS (
SELECT 'val1', 'valX' UNION ALL
SELECT 'valY', 'valZ'
)
-- Solution:
SELECT *
FROM t
WHERE EXISTS (
SELECT 1
-- Join all columns with all values to see if any column matches any value
FROM (VALUES(t.col1),(t.col2)) t1(col)
JOIN (VALUES('val1'),('val2')) t2(val)
ON col = val
)
Of course, one could argue, which version is more concise.
Yes, for example you can do this in Oracle:
select x, y from (select 1 as x, 2 as y from dual)
where (x,y) in (select 1 as p, 2 as q from dual)