SQL Multiple joins with OR condition - sql

I have a following tables:
TableA
id
name
TableB
id
tableA_id
TableC
id
tableA_id
So tables B and C have tableA_id fk.
I need a query which will return all id-s from TableA that have reference in either TableB or TableC.
If I do standard join, it will return only values that have reference in both tables B and C.
I could do this using two queries, one joins B, other joins C and use UNION to merge results, but I dont want to write same query twice.
Is there a way to achieve this 'OR' JOIN??

Try with this
SELECT DISTINCT TABLEA.ID_A, TABLEA.NAME
FROM TABLEA,TABLEB,TABLEC
WHERE TABLEA.ID_A = TABLEB.ID_A AND TABLEA.ID_A = TABLEC.ID_A
Using DISTINCT TAG you eliminate duplicates.

Something like this?
SELECT
*
FROM
TableA,
TableB,
TableC
WHERE
TableA.id = TableB.tableA_id
OR TableA.id = TableC.tableA_id

You can use left outer joins and checks for the ids:
SELECT a.id FROM A a
LEFT JOIN B b ON a.id = b.tableA_id LEFT JOIN C c ON a.id = c.tableA_id
WHERE b.id IS NOT NULL OR c.id IS NOT NULL

Related

SQL antijoin with multiple keys

I'd like to implement an antijoin on two table but using two keys so that the result is all rows in Table A that do not contain the combinations of [key_1, key_2] found in Table B. How can I write this query in SQL?
If you want an anti-left join, the logic is:
select a.*
from tablea a
left join tableb b on b.key_1 = a.key_1 and b.key_2 = a.key_2
where b.key_1 is null
As for me, I like to implement such logic with not exists, because I find that it is more expressive about the intent:
select a.*
from tablea a
where not exists (
select 1 from tableb b where b.key_1 = a.key_1 and b.key_2 = a.key_2
)
The not exists query would take advantage of an index on tableb(key_1, key_2).
select a.*
from table_a a
left anti join table_b b on a.key_1 = b.key_1 and a.key_2 = b.key_2;

SQL query with Left Join to return results when the top 1 column of joined table matches column of main table

I have a main table (TableA) and I'm Left Joining TableB, but I only want to include the first record of TableB where ColumnB of the two tables match. I've gotten this to work in the query below, except I also need to include the records of TableA where no matching record exists for TableB (i.e. in the query below b.ColumnA would be null). I understand why my line below "OR b.ColumnA = null" does not work, but I'm struggling to find a solution that does.
Any reasonable way to ALSO include records of TableA where no matching records exist in TableB
SELECT b.ColumnA, a.ColumnA, a.ColumnB
FROM TableA a
LEFT JOIN TableB b ON b.ColumnB = a.ColumnB
WHERE b.ColumnA = (SELECT TOP 1 bb.ColumnA FROM TableA aa LEFT JOIN TableB bb ON bb.ColumnB = a.ColumnB)
OR b.ColumnA = null
Use OUTER APPLY:
SELECT b.ColumnA, a.ColumnA, a.ColumnB
FROM TableA a OUTER APPLY
(SELECT TOP (1) b.*
FROM TableB b
WHERE b.ColumnB = a.ColumnB
ORDER BY ? -- however you are defining the ordering for "first"
) b;
You can leave out the ORDER BY if you are content with an arbitrary matching record from b. However, the question specifies "first" without defining it.

SQL - not sure how to join tables

I'm trying to join two tables like this:
Table A
ID Value1
1 A
2 B
3 C
Table B
ID Value2
1 A
3 B
4 C
Result should be:
ID Value1 Value2
1 A A
2 B null
3 C B
4 null C
I.e. join Table A to Table B on ID. If ID doesn't exist in Table A, add the ID from Table B.
The closest I've come is:
SELECT
a.ID, a.Value1, b.Value2
FROM
TableA a
OUTER JOIN
TableB b ON a.ID = b.ID
That gives me the new rows from TableB, but the ID is null.
How can I accomplish this?
You are very close, you just need a little push in the right direction:
SELECT COALESCE(a.ID, B.ID) As ID, a.Value1, b.Value2
FROM TableA a
FULL OUTER JOIN TableB b ON a.ID=b.ID
The COALESCE function returns the first parameter it gets that is not null. since this is a full outer join, a.id will be null on one row and b.id would be null on a different row.
Try this:
SELECT *
FROM TableA A
FULL OUTER JOIN TableB B
ON A.ID = B.ID;
Just a note: you should not name your tables in SQL with spaces in them.
Remember the basic for joining different tables
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;
For your case:
SELECT a.value1, b.value2
FROM TableA a
FULL OUTER JOIN TableB b ON a.ID=b.ID
remember full outer join
The FULL OUTER JOIN keyword returns all rows from the table (tableA) and from the table (tableB) and the FULL OUTER JOIN keyword combines the result of both LEFT and RIGHT joins.

How do i join two tables in such a way that all the rows are present in the output

I have two table say TableA and TableB with below structure
TableA
cust_name
cust_id
cust_age
TableB
id
cust_id
balance
I need to join these two tables all retrieve the below columns
tableA.cust_name,tableA.cust_age,tableB.balance
but if I use the below query
select a.cust_name,a.cust_age,sum(b.balance) from tableA a,tableB b
where a.cust_id=b.cust_id and b.id = (select max(id) from tableB where cust_id=b.cust_id)
I only get those rows which are present in both the tables, but i need all the rows where there is a customer in tableA and not in tableB the b.balance should come either null or 0.
I would say Left join
SELECT a.cust_name, a.cust_age, sum(nvl(b.balance,0))
FROM tableA a
LEFT JOIN tableB b
ON a.cust_id=b.cust_id
GROUP BY a.cust_name, a.cust_age
Also use NVL as you may get some nulls in b.balance.
Alternatively if you are on an old Oracle version you have to use a different join:
SELECT a.cust_name, a.cust_age, sum(nvl(b.balance,0))
FROM tableA a, tableB b
where a.cust_id=b.cust_id (+)
GROUP BY a.cust_name, a.cust_age

3 table sql join

I need to join tableA, tableB, and tableC, but it's possible that tableB won't have a corresponding row. Posted below is how I am currently doing the query. The problem with it is that if tableB doesn't have a correspoinding row, it won't return a result. My sql skills are very rusty so I appreciate your help. Thanks.
SELECT [column names]
FROM tableA AS a, tableB AS b, tableC as c
WHERE b.blah = a.blah
AND c.foo = a.foo
AND [more where conditions]
Don't use the , syntax. Use JOIN to allow for a readable LEFT JOIN...
SELECT
*
FROM
tableA
LEFT JOIN
tableB
ON TableB.x = TableA.y
LEFT JOIN
tableC
ON TableC.x = TableB.y
AND TableC.y = TableA.z
Use a LEFT JOIN.
SELECT [column names]
FROM
tableA AS a
LEFT JOIN tableB AS b ON b.blah = a.blah
JOIN tableC as c ON c.foo = a.foo
SELECT [column names]
FROM tableA AS a INNER JOIN tableC as c ON (c.foo = a.foo)
LEFT OUTER JOIN tableB as B on (b.blah = a.blah)
WHERE [more where conditions]
If the [more where conditions] are on B, then you need to include them in the OUTER JOIN ON clause.
The terminology here (so you can look up more details) is an Outer Join. The other answer(s) are fine -- but watch out for whether you want an INNER or OUTER join on table c (do you want records returned if there are no matching rows in tableC)? Here is a link for the general issue.
http://www.w3schools.com/sql/sql_join_left.asp