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

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)

Related

Using the result from a subquery elsewhere in the query

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

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

SQL query two queries and union

I've these two approaches for a problem and they look kind of okay to me. Is there a better way to do this? Please advise.
X,Y,Z are same for both queries
Two queries and add the values:
select sum(columnA1), sum(columnA2) from tableA
where columnA3 = X and columnA4 = Y and columnA5 = Z;
select sum(columnB1) from tableB
where columnB3 = X and columnB4 = Y and columnB5 = Z;
Union All:
select sum(columnA1), sum(columnA2), sum(columbB1)
from (select columnA1, columnA2, null from tableA
where columnA3 = X and columnA4 = Y and columnA5 = Z
union all
select null, null, columnB1 from tableB
where columnB3 = X and columnB4 = Y and columnB5 = Z) unionresult
Each of your 2 options will produce the same 3 numeric results, the only real difference is in the delivery (either as 2 queries or as a single, combined, query).
I cannot really know which suits your purpose best, but you are adding a tiny overhead to get get a combined result.
Here is another possible alternative for a combined result but I don't think it's any better than the union all approach you show (& it could even be worse).
SELECT
SUM(columnA1)
, SUM(columnA2)
, (
SELECT
SUM(columnB1)
FROM tableB
WHERE columnB3 = X
AND columnB4 = Y
AND columnB5 = Z
) as sum_columnB1
FROM tableA
WHERE columnA3 = X
AND columnA4 = Y
AND columnA5 = Z
;

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.