Using the result from a subquery elsewhere in the query - sql

I have the following pseudo-sqlite call:
SELECT x, y,
(SELECT --very long SQL call--) AS z,
(SELECT a FROM diff_table_name WHERE b = z) AS e
FROM table_name
WHERE c = d
Essentially I want to use the z variable result from the first subquery in the second subquery, but I get a
no such column: z
error when I do. I can repeat the very long SQL call in the second subquery and that works, but I was hoping to not have to do that. Or maybe there's a way to return both a and z from one subquery?

This part of your query:
SELECT x, y,
(SELECT --very long SQL call--) AS z
FROM table_name
WHERE c = d
can be safely wrapped inside a CTE and then use the value of z:
WITH cte AS (
SELECT x, y,
(SELECT --very long SQL call--) AS z
FROM table_name
WHERE c = d
)
SELECT x, y, z,
(SELECT a FROM diff_table_name WHERE b = z) AS e
FROM cte

Related

Are SQL tuples, when used as predicates, just a syntactic sugar for expanded logical AND's?

Are SQL tuples, when used as predicates, just a syntactic sugar for expanded logical AND's or there is more to it?
eg.
with tmp1(c1,c2,c3) as (
select * from (
values(1,'a','apple')
,(2,'b','ball')
,(3,'c','cat')
,(4,'d','dog')
,(5,'e',null)
)
)
select * from tmp1 where (c1,c2,c3) = (1,'a','apple');
is equivalent to
select * from tmp1 where c1 = 1 and c2 = 'a' and c3 = 'apple';
and similarly for IN clause or JOIN's
I did check for NULL awareness(if it would get translated to the form x IS NOT DISTINCT FROM y) but atleast DB2 isn't
select * from tmp1 where (c1,c2,c3) = (5,'e',null); -- Empty resultset
When you are strictly considering scalar equality, yes, it's equivalent.
There are other not-so-simple cases:
When you consider predicates with a set operator like IN or NOT IN then it's a more powerful construct, as in:
(a, b, c) in (select x, y, z...)
(a, b, c) not in (select x, y, z...)
When the predicate includes a tuple inequality. This is specially useful in query pagination. For example:
(a, b, c) >= (x, y, z)
without tuples it the syntax would be much more verbose, as in:
a > x OR a = x AND (b > y OR b = y AND c >= z)

"SELECT column ... WHERE", knowing value of other column, can't use subquery

I'm working on this SELECT query:
SELECT * FROM x
JOIN y ON x.struktorg = y.ref
WHERE y.rodzic = (SELECT ref FROM y WHERE y.symbol = 'the value i know')
The goal is to not use subselect. I know the value of symbol column, but the table that I need to get results from doesn't use it. It uses the reference number of that value.
you can join to y one more time:
SELECT * FROM x
JOIN y y1 ON x.struktorg = y1.ref
join y y2
ON y1.rodzic = y2.ref
and y2.symbol = 'the value i know'
but I don't see any benefit using join over subquery in this scenario .
if the subquery table y is the same of the JOIN y, then you can do this
SELECT *
FROM x
JOIN y ON x.struktorg = y.ref and y.rodzic = y.ref and y.symbol = 'the value i know'
if the subquery table y is diferent of the JOIN y, then you can do this renaming subquery table y for z
SELECT * FROM x
JOIN y ON x.struktorg = y.ref
JOIN z ON y.rodzic = z.ref and z.symbol = 'the value i know'
I would go around the sub-select by creating a temporary table first, like in the example below:
SELECT ref INTO #TEMP_TABLE FROM y WHERE y.symbol = 'the value i know'
Then I would join on that temporary table I created like in the example here:
SELECT * FROM x
JOIN y ON x.struktorg = y.ref
JOIN #TEMP_TABLE z on z.ref = y.rodzic
Having said that, I am sure that the above solution works effectively for SQL Server. However, I've never used Firebird, so the principles there might be different.

Can I use multiple queries inside SELECT EXISTS()?

Is it possible to write multiple queries inside the SQL EXISTS()?
Just as this example
SELECT
EXISTS (SELECT a FROM at WHERE X = :X;
SELECT b FROM bt WHERE Y = :Y;
SELECT C FROM ct WHERE Z = :Z;
)
And in case it is possible, is this the best way to check the existence of an element inside multiple tables? or using UNION ALL or JOIN would be better?
Use OR:
EXISTS (SELECT a FROM at WHERE X = :X) OR
EXISTS (SELECT b FROM bt WHERE Y = :Y) OR
EXISTS (SELECT C FROM ct WHERE Z = :Z)
This would normally be in a WHERE or CASE, not a SELECT.
You can use UNION ALL, but this is usually more efficient.

SQL UPDATE Statement on complex select query

I have a complex select query with many joins. It is generate from a tool. I have to update a field based on that query.
I tried to decode it but not sure that updating based on my decode is correct. Can I update the values based on the tool generated query. Like below:-
UPDATE F_Sales SET d_source = "XYZ" WHERE
F_Sales.customer_code in (SELECT A, B, C, D......... FROM K, L, M, N, O,P ....)
create table #temp(customer_code INT)
insert into #temp SELECT A, B, C, D......... FROM K, L, M, N, O,P ....
UPDATE F_Sales SET d_source = "XYZ"
FROM F_Sales join #temp ON
F_Sales.customer_code = #temp.customer_code
Provided one of the A,B, .. columns (column D for example) can be mapped to F_Sales.customer_code
UPDATE F_Sales SET d_source = "XYZ"
WHERE
F_Sales.customer_code in (
SELECT D
FROM ( -- untouched original query
SELECT A, B, C, D......... FROM K, L, M, N, O,P ....) q
)
or
UPDATE F_Sales SET d_source = "XYZ"
FROM F_Sales
JOIN ( -- untouched original query
SELECT A, B, C, D......... FROM K, L, M, N, O,P ....) q
ON F_Sales.customer_code = q.D
Probably we can make it much better if you can show the generated query

Join Multiple Rows into 1 row different columns SQL Server

I am working on a query and would love some help.
I will provide a simplified version of the query in hopes that it communicates what I am attempting to do.
Given the following Tables:
TableA (RecordNumber, TableAID, SomeValue)
TableB (RecordNumber, X, Y, Z)
TableC (RecordNumber, D, E, F, G)
The result set I am looking for:
TableB.RecordNumber, X, Y, Z, D, E, F, G, SomeValue1, SomeValue2, SomeValue3, SomeValue4
My query currently is
Select
TableB.RecordNumber, X, Y, Z, D, E, F, G, SomeValue1)
inner join
TableC on TableB.RecordNumber = TableC.RecordNumber
inner join
TableA on TableB.RecordNumber = TableA.RecordNumber
I realize that this is returning 1 row per SomeValue in TableA.
What I would like to do is combine each row for a RecordNumber into 1 row populating the SomeValueX with the SomeValue value from row X for that record number.
Thoughts?
You can't have a variable number of columns without using dynamic SQL but you can have a variable number of comma-separated values in a single column.
SELECT b.RecordNumber, X, Y, Z, D, E, F, G,
STUFF((
SELECT ',' + SomeValue
FROM TableA a
WHERE a.RecordNumber = b.RecordNumber
ORDER BY SomeValue
FOR XML PATH('')
), 1, 1, '') AS SomeValues
FROM TableB b
INNER JOIN TableC c
ON b.RecordNumber = c.RecordNumber
If TableA.SomeValue is not of a character or string data type, you would also want to cast it to a varchar of an appropriate length.