How to use NOT IN with the Union Result - sql

I am trying to get the distinct values from one table having different conditions.
The Query that I am using is
Select A.*
from A
where A.x not in (select B.x from B
union
select C.x from C
)
Please note that I have been using CTE to get the different values.
When I standalone run this select B.x from B union select C.x from C
I see the output.
Same goes for table A also.
But when I run it together I see no data.

One way is to use not exists
Select A.* from A where
not exists (select 1 from b where b.x = A.x)
and
not exists (select 1 from c where c.x = A.x)

;with tabletemporary
AS
(
SELECT b.x AS name from b UNION SELECT c.x AS name FROM c
)
Select a.* FROM a WHERE a.x NOT IN
(SELECT name FROM tabletemporary)
you can use this code

Related

Can i run more then one main select statments on the 2 with tables?

Hay All,
is it possible to run more than 1 select statement after using with?
first select statement works fine, as soon as i add another select statement i got a error.
with
a as (select a,b,c from Table1 with(readuncommitted)),
b as (select d,e,f from Table2 with(readuncommitted))
select * from a
select * from b
expected output:
Table 1
a
Table 2
b
Well the way CTEs will behave is that they will only be in scope for the first query, but not the second. You could perhaps do a union query here:
SELECT a, b, c, 'Table1' AS src FROM a
UNION ALL
SELECT d, e, f, 'Table2' FROM b;
Or, you could move the b CTE to before the second query:
WITH a AS (
SELECT a, b, c
FROM Table1
WITH(readuncommitted)
)
SELECT * FROM a;
WITH b AS (
SELECT d, e, f
FROM Table2
WITH(readuncommitted)
)
SELECT * FROM b;
hay DasD,
You can not use multiple select for cte, but you can use more than one CTE like this.
with
a as (select a,b,c from Table1 with(readuncommitted)),
b as (select d,e,f from Table2 with(readuncommitted))
select * from a,b
You have to explain to the database, what you wantfrom bith tables.
as both have the same structure you can use UNION to join them vertically
with
a as (select a,b,c from Table1 with(readuncommitted)),
b as (select d,e,f from Table2 with(readuncommitted))
select * from a
UNION
select * from b
From the docs:
"A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE statement that references some or all the CTE columns."
Source

How could I DRY this SQL which UNION ALL two similar statements?

I need to UNION the results of the same SELECT code over two different schemas. (Example below.) But every time I need to change something in the code, I have to change it twice. I've already been bitten for forgetting to make the change in the second SELECT. Is there a way to abstract the SELECT statement to some sort of function?
This is a query saved on a .sql file, which I run sometimes. I do not have permissions to create views or functions to the DB.
SELECT a.column_a,
b.column_b,
c.column_c
FROM schema_A.table_a AS a,
schema_A.table_b AS b,
schema_A.table_c AS c
WHERE a.id_b = b.id
AND b.id_c = c.id
AND a.column_a LIKE 'something%'
UNION ALL
SELECT a.column_a,
b.column_b,
c.column_c
FROM schema_B.table_a AS a,
schema_B.table_b AS b,
schema_B.table_c AS c
WHERE a.id_b = b.id
AND b.id_c = c.id
AND a.column_a LIKE 'something%'
I'd like to be able to do something like this:
FUNCTION something(#schema) AS (
SELECT a.column_a,
b.column_b,
c.column_c
FROM #schema.table_a AS a,
#schema.table_b AS b,
#schema.table_c AS c
WHERE a.id_b = b.id
AND b.id_c = c.id
AND a.column_a LIKE 'something%'
)
SELECT something(schema_A)
UNION ALL
SELECT something(schema_B)
You could do:
SELECT a.column_a,
b.column_b,
c.column_c
FROM (select * from schema_A.table_a
union all
select * from schema_B.table_a
) AS a,
(Select * from schema_A.table_b
union all
Select * from schema_b.table_b
) AS b,
(select * from schema_A.table_c
union all
select * from schema_B.table_c
) AS c
WHERE a.id_b = b.id
AND b.id_c = c.id
AND a.column_a LIKE 'something%'
But that would not make life easier....... 😉
EDIT: My assumption that above statement has the same result as te original query is wrong, see DBFIDDLE.
I need more ☕☕ to know why ... 😉

Sub-select in select clause and using with its value

There is a way to return the sub-select and return manipulate that depend on this field ?
For example, can I do something like this:
select a, (select top 1 b from b) as b, (a * b) as c
from a
select a, b, (a * b) as c
from (
select a, (select top 1 b from b) as b
from a
) x
Put the subquery in the from clause:
select a.a, b.b, (a.a * b.b) as c
from a cross join
(select top 1 b from b) b;

SQL-TABLE CREATION

Please explain to me the use of the comma after 'FROM TABLE_ABC A'. how does it work in the execution of the sql query.
CREATE TABLE ABCD AS
( SELECT A.*
FROM TABLE_ABC A,
(SELECT COL_1,COL_2 FROM
(SELECT B.*,C.* FROM
TABLE_XYZ B, TABLE_MNO C
WHERE B.COL_X=C.COL_Y
)D
)A.COL_C=D.COL_D
)
WITH DATA PRIMARY INDEX(SASAJS)
It is similar to join
select * from #tempA ta join #tempB tb
on ta.ID = tb.ID
same as
select * from #tempA ta, #tempB tb
where ta.ID = tb.ID
Using JOINS makes the code easier to read
You're using a select to create a 2nd table that is also created from another subselect. See it like this and you'll understand it better:
CREATE TABLE ABCD AS(
SELECT
A.*
FROM
TABLE_ABC A,
(
SELECT
COL_1,
COL_2
FROM
(
SELECT
B.*,
C.*
FROM
TABLE_XYZ B,
TABLE_MNO C
WHERE
B.COL_X = C.COL_Y
) D
)
WHERE
A.COL_C = D.COL_D
) WITH DATA PRIMARY INDEX(SASAJS)
but your original code is lacking a WHERE CLAUSE before A.COL_C = D.COL_D. I included it.
I'm assuming that B.* or C.* has a column named COL_D AND A also has it. It would also be better if the D as after the ) before the last WHERE

Where one or another column exists in a sub select

I'm looking to do something like this:
SELECT a, b, c, d FROM someTable WHERE
WHERE a in (SELECT testA FROM otherTable);
Only I want to be able to test if 2 columns exist in a sub select of 2 columns.
SELECT a, b, c, d FROM someTable WHERE
WHERE a OR b in (SELECT testA, testB FROM otherTable);
We are using MS SQL Server 2012
Try this
SELECT a, b, c, d
FROM someTable WHERE
WHERE a IN (SELECT testA FROM otherTable)
OR b IN (SELECT testB FROM otherTable)
or
SELECT a, b, c, d
FROM someTable WHERE
WHERE EXISTS
(SELECT NULL
FROM otherTable
WHERE testA = a OR testB = a
OR testA = b OR testB = b)
UPDATE:
Maybe you need to add index on testB column, if you have bad performance.
Also another option to use CROSS APPLY for MS SQL
SELECT a, b, c, d
FROM someTable ST
CROSS APPLY (
SELECT 1
FROM otherTable OT
WHERE OT.testA = ST.a OR OT.testB = ST.b
)
If any of this won't work, try using UNION. Mostly UNION gives better performance than OR
SELECT a, b, c, d
FROM someTable WHERE
WHERE a IN (SELECT testA FROM otherTable)
UNION
SELECT a, b, c, d
FROM someTable WHERE
WHERE b IN (SELECT testB FROM otherTable)
UPDATE 2:
For further reading on OR and UNION differences
Why is UNION faster than an OR statement
Try this..
SELECT a, b, c, d
FROM someTable
WHERE Exists
(
SELECT 1
FROM otherTable
Where a = testA OR b = testB
)
If I'm understanding your question correctly, LEFT JOIN is probably the way to go here:
SELECT a, b, c, d
FROM TableA ta
LEFT JOIN TableB tb
ON ta.a = tb.a
AND ta.b = tb.b
WHERE tb.a IS NOT NULL
AND tb.c IS NOT NULL
You could also use UNION and INNER JOIN:
SELECT a, b, c, d
FROM someTable
INNER JOIN OtherTable OT on someTable.B = OT.testB
UNION
SELECT a, b, c, d
FROM someTable
INNER JOIN OtherTable OT ON someTable.A= OT.testA
Note that the JOIN approach should be orders of magnitude faster if you have an index on the column
Joins seems to be one option, have you thought about using them with a Union?
SELECT a, b, c, d
FROM someTable
INNER JOIN OtherTable OT on someTable.B = OT.testB
UNION
SELECT a, b, c, d
FROM someTable
INNER JOIN OtherTable OT ON someTable.A= OT.testA