I'm building matching rules for data reconciliation systems and need your advise on adjusting my sql for it as it currently doesn't return what I need.
There are 2 source tables:
Table X Table Y
--------------------- ----------------------
Exec_ID From To Exec_ID From To
1 A B 1 B C
2 A B 2 B C
3 A B 3 B C
4 A B
5 B C
Matching conditions are:
X.To = Y.From
X.Exec_ID = Y.Exec_ID
if there is A -> B and then B -> C, it should return A -> C in the end.
if there is only A -> B and no further B -> C, it should return A -> B.
So the output should be the following.
From To
---------
A C
A C
A C
A B
SQL I'm using is:
select X.From, Y.To
from x
left outer join y on
x.To = Y.From
and x.Exec_ID = y.Exec_ID
It returns the values like
A C
A C
A C
A Null
So the last record is incorrect as it should be A B. Please help to adjust.
Check for null?
select X.From, [To] = COALESCE(Y.To, X.To)
from x
left outer join y on
x.To = Y.From
and x.Exec_ID = y.Exec_ID
Related
I couldn't find exactly what I'm looking for in another thread.
Let's say I have these two tables:
left:
x
left_y
a
1
a
2
b
4
b
5
right:
x
right_y
a
2
a
3
b
5
b
6
I want to run a query close to this in intention:
SELECT *
FROM left FULL OUTER JOIN right
ON (left.x = right.x AND left.left_y = right.right_y)
OR left.x = right.x
And get an output that has no nulls in x, but maybe has a null in left_y or right_y
x
left_y
right_y
a
1
null
a
2
2
a
null
3
b
4
null
b
5
5
b
null
6
You can use coalesce:
select coalesce(l.x, r.x) as x,
left_y,
right_y
from l full outer join r
on l.x = r.x
and l.left_y = r.right_y
Fiddle
If I have 3 tables A, B and C I understand how to use left join to join them like this:
SELECT *
FROM A LEFT JOIN
B
ON A.col = B.col LEFT JOIN
C
on B.col = C.col
So A to B then B to C
How would I do this:
SELECT *
FROM A LEFT JOIN
B
ON A.col = B.col LEFT JOIN
C
on A.col = C.col
So A to B and then A to C
Would really appreciate any help
I don't see anything wrong with what you're trying to accomplish.
A simple example is at: http://sqlfiddle.com/#!9/6dbbe2/2
There are three tables (A, B, and C):
Table A
id name
1 Alice
2 Bob
3 Carol
4 Don
5 Edith
Table B
id id_A pet
1 5 Tex
2 4 Socks
3 2 Rex
4 1 Percy
5 1 Quinlan
Table C
id id_A hobby
1 1 acting
2 2 boxing
3 4 dancing
4 5 eating
Tables B and C relate to Table A through the id_A foreign key.
A query like you have:
SELECT * FROM A LEFT JOIN B
ON A.id = B.id_a LEFT JOIN C
ON A.id = C.id_a;
works just fine.
Suppose I have a table A as a 'dictionary':
A type code name
1 a x
1 b y
2 a z
2 b t
I want to translate the following table B in to names:
B c1 c2
a a
a b
b b
Where B.c1 is the code of A.type=1 and B.c2 is the code of A.type=2.
The expected result is
x z
x t
y t
If there is only one column in B needs to be translated, it is easy.
SELECT A.name
FROM A, B
WHERE A.type = 1
AND B.c1=A.code
Using joins;
select a1.type,b.c1,a2.type,b.c2 from b
left outer join a as a1 on b.c1= a1.code and a1.type=1
left outer join a as a2 on b.c2= a2.code and a2.type=2
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
I would like to know what's the logic for multiple joins (for example below)
SELECT * FROM B returns 100 rows
SELECT B.* FROM B LEFT JOIN C ON B.ID = C.ID returns 120 rows
As I know using left join will returns any matching data from the left table which is B if data are found for both table. But how come when using left join, it returns more data than table B itself?
What am I do wrong or misunderstood here? Any guidance are very appreciated. Thanks in advance.
Let be table B:
id
----
1
2
3
Let be table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Any id from b is matched with ids from c, then id=2 will be matched twice. So a left join on id will return 4 rows even if base table B has 3 rows.
Now look at a more evil example:
Table B
id
----
1
2
2
3
4
table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Every id from b is matched with ids from c, then first id=2 will be matched twice and second id=2 will be matched twice so the result of
select b.id, c.name
from b left join c on (b.id = c.id)
will be
id name
------------
1 John
2 Mary
2 Mary
2 Anne
2 Anne
3 Stef
4 (null)
The id=4 is not matched but appears in the result because is a left join.
Look at the following example :
B = {1,2}
C = {(1,a),(1,b),(1,c),(1,d),(1,e)}
The result of B left join C will be :
1 | a
1 | b
1 | c
1 | d
1 | e
2 | null
The number of rows in the result is definitely larger than rows in B (2).
In general the number of rows in result of B left join C is bounded by B.size + C.size and not only by B.size as you think...
As per your query it do the join to B Table with C and B table is Left Table so it will display all the records of Left table in our case it is B and related from other Table in our Case it is C.