Join when exact match other other wise join with default value - sql

I have two table a and b
table a
ID
a
b
c
table b
ID Value
a 1
b 2
default 0
So I want to join two tables on ID when exactly matching, otherwise use default value
The desired results
ID Value
a 1
b 2
c 0

Use a LEFT OUTER JOIN for that purpose like
select t1.ID, COALESCE(t2.Value, 0) as Value
from tablea t1
left join tableb t2 on t1.ID = t2.ID;

Try this:
SELECT a.ID, b.Value
FROM a
INNER JOIN b
ON a.ID = b.ID
UNION ALL
SELECT a.ID, b.Value
FROM a
CROSS JOIN b
WHERE
a.id <> b.id
This will provide you with all matching IDs, then the UNION of the CROSS JOIN query should provide the default value for non-matching IDs.

Try this:
SELECT t1.ID,
COALESCE(t2.Value, (SELECT Value FROM tableb t3 WHERE ID ='default')) AS Value
FROM tablea t1
LEFT JOIN tableb t2 on t1.ID = t2.ID;

Related

SQL Self Join and take a record by a condition on a third join

I have a query where I'm doing a self join on TableA on 'Id1' and 'Id2'. I then do an inner join on TableB. The table with the self join as 2 keys (Id1,Id2). I'm trying to get the records that do not match up with the Id in Table3. Is it a condition that I need to add on the join? Thanks!
SELECT *
FROM TableA t1
JOIN TableA t2 ON t1.Id1 = t2.Id2
JOIN TableB t3 ON t1.Id1 = t3.Id
EDIT :
SELECT *
FROM UCDetails ucd1
JOIN MS et ON ucd1.UKey = TRY_CAST(et.SubKey AS bigint)
JOIN dbo.UCDetails ucd2 ON ucd1.UKey = ucd2.ETTSubkey
WHERE ucd1.ETTSubkey IS NULL
Sorry, I should of been more specific, so here is the query. What I want is to take only the record from ucd1 or ucd2 where if the ucd1 ETTSubkey IS NULL and the 'UKey' DOES NOT match the 'et.Subkey'. I can pull the records with this join but I only want to take the 'UCD' record where there isn't a match with the 'Subkey' on the et table.
If you want rows where either id does not match in tableB, then use not exists:
select a.*
from tableA a
where not exists (select 1
from tableB b
where b.id = a.id1
) or
not exists (select 1
from tableB b
where b.id = a.id2
) ;
I'm trying to get the records that do not match up with the Id in
Table3
If by match up you mean that TableB's Id is equal to either Id1 or Id2 in TableA, then you only need a LEFT join that filters out the matching rows:
SELECT a.*
FROM TableA a LEFT JOIN TableB b
ON b.Id IN (a.Id1, a.Id2)
WHERE b.Id IS NULL

Inner joining on multiple tables but only selecting one

I am joining two different tables to my original table, but I want to only inner join on one of the two (depending on if it is the one that contains a matching key). Basically, it will be impossible for both table that are being joined to have the same record as the original. I need at most one.
Something like...
SELECT
t.Id,
t.column1,
t.column2,
a.column3 as ‘Column 3’,
b.column4 as ‘Column x’,
s.column5,
t.column6
FROM “Table1” t
INNER JOIN “Table2” a on a.Id = t.Id
INNER JOIN “Table3” b on b.Id = t.Id
Only one of 2 or 3 should be joined on if the Id exists in that specific table.
You can use left join:
SELECT t.*,
a.column3 as Column3,
b.column4 as Columnx
FROM Table1 t LEFT JOIN
Table2 a
ON a.Id = t.Id LEFT JOIN
Table3 b
ON b.Id = t.Id;
This is often used with coalesce():
SELECT t.*, coalesce(a.col1, b.col1) as col1
FROM Table1 t LEFT JOIN
Table2 a
ON a.Id = t.Id LEFT JOIN
Table3 b
ON b.Id = t.Id;

XOR JOIN in SQL

I have the following tables
Table A
ID "Other Columns"
1
2
3
Table B
ID "Other Columns"
3
4
5
What is the efficient way to return the below result?
Result
ID "Other Columns"
1
2
4
5
A full outer join should work, and only go through each table once. They can be tricky, so test carefully!
SELECT
isnull(A.ID, B.ID) ID
,"Other columns" -- Handle nulls properly!
from TableA A
full outer joing TableB B
on B.ID = A.ID
where not (A.ID is not null
and B.ID is not null)
You want to use left and right join and union them
Select TableA.ID as 'ID','Other Colums'
FROM TableA Left join TableB
ON TableA.ID=TableB.ID
WHERE TableB.ID IS NULL
UNION
Select TableB.ID as 'ID','Other Colums'
FROM TableA Right join TableB
ON TableA.ID=TableB.ID
WHERE TableA.ID IS NULL
You can try like this
SELECT
COALESCE(a.id, b.id),
OtherColumns
FROM #tablea a
FULL JOIN #tableb b
ON a.id = b.id
WHERE a.id IS NULL
OR b.id IS NULL
You can do this with a UNION ALL using a LEFT JOIN to determine if the ID is not in the other table. Keep in mind that the column count and datatypes between the two tables must match up:
Select A.Id, A.OtherColumns
From TableA A
Left Join TableB B On A.Id = B.Id
Where B.Id Is Null
Union All
Select B.Id, B.OtherColumns
From TableB B
Left Join TableA A On A.Id = B.Id
Where A.Id Is Null
Not quite sure what you need with the "Other columns", but you could use EXCEPT:
Select ID from TableA
EXCEPT
Select ID from TableB
If you need Other columns from TableA you could use:
Select ID, OtherColumn1, OtherColumn2 from TableA
where ID not in (select ID from TableB)
(as long as ID cannot be null in TableB)
I broke down each part to be clearer!
select *
into #temp
from
TabA Full outer join TabB
on TabA.ColNameA = TabB.ColNameB
select *
into #temp2
from #temp
where (ColNameA is Null Or ColNameB is null)
select ColNameA from #temp2
where ColNameA Is not null
union
select ColNameB from #temp2
where ColNameB Is not null

sql, outer join

I have two tables, linked with an outer join. The relationship between the primary and secondary table is a 1 to [0..n]. The secondary table includes a timestamp column indicating when the record was added. I only want to retrieve the most recent record of the secondary table for each row in the primary. I have to use a group by on the primary table due to other tables also part of the SELECT. There's no way to use a 'having' clause though since this secondary table is not part of the group.
How can I do this without doing multiple queries?
For performance, try to touch the table least times
Option 1, OUTER APPLY
SELECT *
FROM
table1 a
OUTER APPY
(SELECT TOP 1 TimeStamp FROM table2 b
WHERE a.somekey = b.somekey ORDER BY TimeStamp DESC) x
Option 2, Aggregate
SELECT *
FROM
table1 a
LEFT JOIN
(SELECT MAX(TimeStamp) AS maxTs, somekey FROM table2
GROUP BY somekey) x ON a.somekey = x.somekey
Note: each table is mentioned once, no correlated subqueries
Something like:
SELECT a.id, b.*
FROM table1 a
INNER JOIN table2 b ON b.parentid = a.id
WHERE b.timestamp = (SELECT MAX(timestamp) FROM table2 c WHERE c.parentid = a.id)
Use LEFT JOIN instead of INNER JOIN if you want to show rows for IDs in table1 without any matches in table2.
select *
from table1 left outer join table2 a on
table1.id = a.table1_id
where
not exists (select 1 from table2 b where a.table1_id = b.table1_id and b.timestamp > a.timestamp)
The quickest way I know of is this:
SELECT
A.*,
B.SomeField
FROM
Table1 A
INNER JOIN (
SELECT
B1.A_ID,
B1.SomeField
FROM
Table2 B1
LEFT JOIN Table2 B2 ON (B1.A_ID=B2.A_ID) AND (B1.TimeStmp < B2.TimeStmp)
WHERE
B2.A_ID IS NULL
) B ON B.A_ID = A.ID

sql query without outer join key word

Is it possible to write a sql query where you know you have to use the left outer join..but cannot or are not allowed to use the "outer join" Key Word
I have two table sand want to get rows with null vaues from the left table ...this is pretty simple ...but am not supposed to use the key word....outer join....I need to right the logic for outer join myself
SELECT Field1
FROM table1
WHERE id NOT IN (SELECT id FROM table2)
SELECT Field1
FROM table1
WHERE NOT EXISTS (SELECT * FROM table2 where table2.id = table1.id)
This is something people do but it is deprecated and it does not currently work correctly (it sometimes will return a cross join instead of a left join) so it should NOT be used. I'm telling this only so you avoid using this solution.
SELECT Field1
FROM table1, table2 where table1.id *= table2.id
;WITH t1(c,d) AS
(
SELECT 1,'A' UNION ALL
SELECT 2,'B'
),t2(c,e) AS
(
SELECT 1,'C' UNION ALL
SELECT 1,'D' UNION ALL
SELECT 3,'E'
)
SELECT t1.c, t1.d, t2.c, t2.e
FROM t1, t2
WHERE t1.c = t2.c
UNION ALL
SELECT t1.c, t1.d, NULL, NULL
FROM t1
WHERE c NOT IN (SELECT c
FROM t2
WHERE c IS NOT NULL)
Returns
c d c e
----------- ---- ----------- ----
1 A 1 C
1 A 1 D
2 B NULL NULL
(Equivalent to)
SELECT t1.c, t1.d, t2.c, t2.e
FROM t1
LEFT JOIN t2
ON t1.c = t2.c
For SQL Server, you can just use LEFT JOIN - the OUTER is optional, just like INTO in an INSERT statement.
This is the same for all OUTER JOINs.
For an INNER JOIN you can just specify JOIN with no qualifiers and it is interpreted as an INNER JOIN.
This will give you all the rows in table A that don't have a matching row in table B:
SELECT *
FROM A
WHERE NOT EXISTS (
SELECT 1
FROM B
WHERE A.id = B.id
);
Returns all the matching rows from both tables:
SELECT a.*,b.* FROM table_a a, table_b b
WHERE a.key_field = b.key_field
Potential drawback is non-matches will be skipped.