Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Join tables ON A ∩ B conditions

Tags:

sql-server

I wish to join two (or more) tables based on a set of columns that are present in all tables that take part in the join. In other words I wish to join tables based on the intersection set of columns. However each table has extra columns which are unique to that table.

Intersection set

Example

#: A number
-: NULL

Table A

+------+------+------+
| Col1 | Col2 | ColA |
+------+------+------+
| A    | A    | #    |
| A    | B    | #    |
+------+------+------+

Table B

+------+------+------+
| Col1 | Col2 | ColB |
+------+------+------+
| A    | A    | #    |
| B    | B    | #    |
+------+------+------+

Result

+------+------+------+------+
| Col1 | Col2 | ColA | ColB |
+------+------+------+------+
| A    | A    | #    | #    |
| A    | B    | #    | -    |
| B    | B    | -    | #    |
+------+------+------+------+

I've come up with a solution but the performance is horrid, performance is an issue. I don't want to pollute you with that solution. I'd much rather have a fresh set of eyes on this :)

Looking forward to seeing your solutions. Thank you for your time. It's much appreciated.

UPDATE

Thank you for all the responds. However it seems I didn't explain the problem well enough. (Haven't tested all answers yet)

But note how Table B has a row that's not present in Table A.

Table B
+------+------+------+
| Col1 | Col2 | ColB |
+------+------+------+
| B    | B    | #    |
+------+------+------+

And Table A vice versa.

The solution I've come up with unions all tables together on the intersection set of columns to generate a skeleton.

Skeleton:    
SELECT Col1, Col2 FROM TableA
UNION
SELECT Col1, Col2 FROM TableB

Once I have the skeleton I LEFT OUTER JOIN for each table.

LEFT OUTER JOIN TableA AS a ON a.Col1=skeleton.Col1 AND a.Col2=skeleton.Col2
LEFT OUTER JOIN TableB AS b ON b.Col1=skeleton.Col1 AND b.Col2=skeleton.Col2

So the final query looks like this

SELECT s.*, a.ColA, b.ColB 
FROM 
(
    SELECT Col1, Col2
    FROM TableA
    UNION
    SELECT Col1, Col2
    FROM TableB
) s
LEFT OUTER JOIN TableA a ON a.Col1=s.Col1 AND a.Col2=s.Col2
LEFT OUTER JOIN TableB b ON b.Col1=s.Col1 AND b.Col2=s.Col2
like image 754
Snæbjørn Avatar asked Jun 12 '12 19:06

Snæbjørn


People also ask

How do you join tables based on conditions?

You join two tables by creating a relationship in the WHERE clause between at least one column from one table and at least one column from another. The join creates a temporary composite table where each pair of rows (one from each table) that satisfies the join condition is linked to form a single row.

What are join conditions?

A join condition defines the way two tables are related in a query by: Specifying the column from each table to be used for the join. A typical join condition specifies a foreign key from one table and its associated key in the other table.

Which join would you use to get an intersection of tables?

An INNER JOIN returns a result set that contains the common elements of the tables, i.e the intersection where they match on the joined condition.

Can you join with or condition?

If you have an OR condition in the JOIN - and there is no possibility that the values in the OR statement overlap...then you can convert it to a UNION ALL. If the values overlap it would require a UNION which may not improve performance over the JOIN.


1 Answers

Just the thing for a full outer join:

select  coalesce(a.Col1, b.Col1) as Col1
.       coalesce(a.Col2, b.Col2) as Col2
,       a.ColA
,       b.ColB
from    A a
full outer join
        B b
on      a.Col1 = b.Col1
        and a.COl2 = b.Col2
like image 156
Andomar Avatar answered Oct 22 '22 22:10

Andomar