Sql finding two columns for values - sql

I have 2 tables joined with inner join with a column
Now rows would have
A B
C D
E G
P Q
Z F
This row I need to compare with Master Relation Table
Column1 Column2
A B
D C
E F
So based on the above condition I need to show records in a report
A B Do Not Show
C D Do Not Show
E G Show
P Q Show
Z F Show

You can do it this using LEFT JOIN:
SELECT T1.Col1,T1.Col2,
CASE WHEN T2.Column1 IS NOT NULL THEN 'Do Not Show' ELSE 'Show' END AS Result
FROM Table1 T1 LEFT JOIN
Table2 T2 ON
(T1.Col1=T2.Column1 AND T1.Col2=T2.Column2)
OR (T1.Col1=T2.Column2 AND T1.Col2=T2.Column1)
Result:
Col1 Col2 Result
---------------------------
A B Do Not Show
C D Do Not Show
E G Show
P Q Show
Z F Show
Sample result in SQL Fiddle

Related

best way to join by multiple columns and avoid OR in SQL

I need a recommendation.
I have two tables. Table 1 is the main table and table 2 is the table that I initially thought to join Table 1 through a left join, table 2 is much larger than table 1. What would be the best performing way to join Table 1 and Table 2 being the union condition that Column b is equal to column b or that column c is equal to column c and column d is equal to column d, that is, any of these conditions is met but no empty values are met. This without using OR in the left join due to the poor performance it would have and the execution time. I appreciate any help.
Note: table 1 and table 2 is the result of 40 lines query. Database do not support recursive query. The database is sap hana.
Table 1
ID
column b
column c
column d
1
d
g
j
2
e
h
k
3
f
i
Table 2
ID_2
column b
column c
column d
4
d
g
5
k
6
i
Desired Result
ID
column b
column c
column d
ID_2
1
d
g
J
4
2
e
h
k
5
3
f
i
6
Use two left joins:
select t1.*,
coalesce(t2_b.id_2, t2_c.id_2, t2_d.id_2) as id_2
from table1 t1 left join
table2 t2_b
on t1.b = t2_b.b left join
table2 t2_c
on t1.c = t2_d.c and t2_b.b is null
table2 t2_d
on t1.d = t2_d.d and t2_c.c is null;
Note that for optimal performance, you want three indexes:
table2(b, id_2)
table2(c, id_2)
table2(d, id_2)

Join only the partitions of two tables

SQL Server 2008
Table A looks like:
A_ID v1 v2 v3
---------------------------
1 d e f
1 a b c
1 a b d
2 d a b
2 e f g
3 d e f
3 e f g
3 d a b
and Table B is similar:
B_ID v1 v2 v3
---------------------------
Q a b c
Q b a c
Q a b d
R d e f
R a b c
R d e f
P e f g
P d a b
What I need back from these two tables are the (A_ID, B_ID) pairs, if any, where each row of Table B where B_ID = any one value has one matching row in Table A where A_ID = any one value. In other words, I need to the complete matching set in A for each full set of triples in B--no super sets or subsets. The value of B_ID and A_ID is immaterial.
I thought partitioning would be the way to go, since I already have the column that naturally partitions A and B, and I also thought I could pre-select which paritions where JOINed by ensuring only partitions with matching numbers of rows would be attempting. I haven't been able to do either--partitioning both tables was easy, but I see no way to tell the join to only act on the partitions.
In this example, (2,P) would be returned because all rows in Set P match all rows in Set 2. Result (1, R) would NOT be returned because all rows of Set R are not matched by all rows of Set 1, etc.
Using symetric difference:
SELECT DISTINCT a1.A_ID, b1.B_ID
FROM A a1,B b1
WHERE NOT EXISTS (
(SELECT v1,v2,v3
FROM A WHERE A.A_ID = a1.A_ID
EXCEPT
SELECT v1,v2,v3
FROM B WHERE B.B_ID = b1.B_ID
)
UNION ALL
(
SELECT v1,v2,v3
FROM B WHERE B.B_ID = b1.B_ID
EXCEPT
SELECT v1,v2,v3
FROM A WHERE A.A_ID = a1.A_ID)
);
LiveDemo

Need to understand how Multiple joins - Left Outer, Right outer, Full outer joins work in a single SQL Query

I have four tables - A,B,C,D. Each table has 1 column: ID.
Data:
Table A = 1,2,3,4
Table B = 1,2,4,5
Table C = 2,3,4,5
Table D = 1,3,5,7
I need help in understanding the output of this SQL query:
select d.*, c.*, b.*,a.*
from d
left join c on d.id = c.id
right join b on b.id = c.id
full outer join a on a.id = b.id;
I am very clear till the left join, but after that when the subsequent joins are applied, I do not understand how the result changes.
As per #Pieter's answer, we can work systematically through this:
Taking just the first LEFT JOIN:
SELECT D.ID AS D, c.ID AS C
from d
left join c
on d.id = c.id
All of Ds rows are returned. NULLS are present for failed joins on C:
D C
1 NULL
3 3
5 5
7 NULL
Then, adding the right join to B:
SELECT D.ID AS D, c.ID AS C, b.ID AS B
from d
left join c
on d.id = c.id
right join b
on b.id = c.id
All of Bs rows are returned, with both C and D being NULL where the join fails.
Only 5 is common to D, C and B.
D C B
NULL NULL 1
NULL NULL 2
NULL NULL 4
5 5 5
Finally, the FULL OUTER JOIN back to A will add missing rows from either side of the JOIN.
This means the '3' from A not present in B is added back, with NULLs for the other columns
D C B A
NULL NULL 1 1
NULL NULL 2 2
NULL NULL 4 4
5 5 5 NULL
NULL NULL NULL 3
Imagine it as a SQL stack machine. Push tables onto the stack as they are encountered, left-to-right, in the FROM clause and perform the join on the two top-most tables as ON clauses are encountered. The result of each join is pushed onto the stack also as it is generated.

how to select distinct values from two tables limit to one row

I have two tables with this values:
**table 1**
id name value
1 A 1
2 B 1
3 F 2
4 G 3
**table 2**
id name value
1 C 1
2 D 1
3 E 2
If I do an inner join of both tables by the value I´m getting this:
A C
A D
B C
B D
F E
But, the problem is that I want only distinct values from both columns like that:
A C
B D
F E
Another set of posible result will be:
A D
B C
F E
There´s no chance of name of table 1 will appear in table 2.
If one value from a column was already selected, it can´t be selected again. This example will be an error because C was already selected:
A C
B C
F E
Any ideas?
In order to pair the records, you need a running number per value to link with. Use row_number() for this.
select t1.name as t1_name, t2.name as t2_name
from
(
select name, value, row_number() over (partition by value order by name) as rn
from table1
) t1
join
(
select name, value, row_number() over (partition by value order by name) as rn
from table2
) t2
on t1.value = t2.value and t1.rn = t2.rn;
SQL fiddle: http://www.sqlfiddle.com/#!4/75de0/1.
Based on the data you provided, and the column you're using to join, you're getting the results you should be getting.
To get your desired results, you would need to join on id, not value
as such:
select a.id, a.name, b.name
from tableA a
inner join tableB b on a.id = b.id

SQL Insert data from 2 table to new table

I want to combine 2 table into 1 table as example below
Table1
100
200
300
Table2
A B C
D E F
G H I
OutputTable
100 A B C
100 D E F
100 G H I
200 A B C
200 D E F
200 G H I
300 A B C
300 D E F
300 G H I
Thank you.
If you already have the new table then:
insert into new_table (field1,field2,field3,field4)
select
a.field1
,b.field2
,b.field3
,b.field4
from a
cross join b
If you do not have the table:
select
a.field1
,b.field2
,b.field3
,b.field4
into new_table
from a
cross join b
Use Cross Join which will create a Cartesian product of two tables
SELECT a.*,b.*
FROM table1 a
CROSS JOIN table2 b
or Use Cross Apply
SELECT a.*,b.*
FROM table1 a
CROSS Apply table2 b