SQL join order and conditions - sql

I've got 3 tables that I want to join and filter on some conditions.
I've first wrote this query:
select * from table1 t1
left join (select * from table2 where table2.fieldX=...) t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where t1.fieldY=...
Then I wanted to make it looks like more canonical by rewritting it like that:
select * from table1 t1
left join table2 t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where table2.fieldX=...
and t1.fieldY=...
But it does not give the same result.
I dont't understand why...
Do you?
Thanks in advance.

When you put table2.fieldX=... in the where clause you eliminate all rows from table1 that do not have a corresponding row in table2. Effectively you are changing the left join into an inner join.
Instead, you can apply the table2 filter in the join itself:
SELECT
*
FROM
Table1 t1
LEFT JOIN Table2 t2 ON t1.id_12 = t2.id_12 AND t2.fieldX = ...
LEFT JOIN Table3 t3 ON t2.id_23 = t3.id_23
WHERE
t1.fieldY = ...

Did you add the inner select where on the second query?
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
on t1.id_12=t2.id_12
LEFT JOIN table3
on t2.id_23=t3.id_23
WHERE t1.fieldY=...
and t2.fieldX=...

Related

How to use Substring in left outer join

I tried to join these 2 tables with ALTERNATE_ID's using substring in left outer join but it doesn't work. Can someone suggest me how to do it.
Here Table1 is master table,
SELECT
tab1.USER_NAME,
tab2.ALTERNATE_ID as 'Contract_no'
FROM TABLE1 tab1
LEFT OUTER JOIN TABLE2 tab2 ON Table2.ALTERNATE_ID = SUBSTRING(tab1.ALTERNATE_ID,0,CHARINDEX('/',tab1.ALTERNATE_ID)
TABLE1:
ALTERNATE_ID 100-0000053-001/0001
TABLE2
ALTERNATE_ID 100-0000053-001
You have to use substring from first char to position of \ - 1
But if you have to join based on part of column, then you should created index on the substring part.
SELECT
tab1.USER_NAME,
tab2.ALTERNATE_ID as 'Contract_no'
FROM TABLE1 tab1
LEFT OUTER JOIN TABLE2 tab2
ON Table2.ALTERNATE_ID
=
SUBSTRING(tab1.ALTERNATE_ID,1,CHARINDEX('/',tab1.ALTERNATE_ID-1)
You can also use SUBSTRING_INDEX to split the string like this:
SELECT tab1.USER_NAME, tab2.ALTERNATE_ID as 'Contract_no'
FROM TABLE1 tab1
LEFT OUTER JOIN TABLE2 tab2
ON Table2.ALTERNATE_ID = SUBSTRING_INDEX(tab1.ALTERNATE_ID, "/", 1);
You can use OUTER APPLY in the following way:
SELECT
tab1.USER_NAME,
tab2.ALTERNATE_ID as 'Contract_no'
FROM TABLE1 tab1
OUTER APPLY (Select ALTERNATE_ID
From TABLE2
Where ALTERNATE_ID=SUBSTRING(tab1.ALTERNATE_ID,1,CHARINDEX('/',tab1.ALTERNATE_ID)-1)) As tab2
If you use PATINDEX, then it's easy to get the position of the digit before the slash.
SELECT *
FROM TABLE1 t1
LEFT JOIN TABLE2 t2
ON t2.ALTERNATE_ID = LEFT(t1.ALTERNATE_ID, PATINDEX('%[0-9]/%', t1.ALTERNATE_ID))
Or looking at it differently, the one in Table1 is like the one in Table2
SELECT *
FROM TABLE1 t1
LEFT JOIN TABLE2 t2
ON t1.ALTERNATE_ID LIKE t2.ALTERNATE_ID+'/%'
Demo on db<>fiddle here

Inner join the tables where the value of one column is different. But the meaning of the values are same

Table t1
Table t2
I tried running the query
select CountyCode, ContactPerson
from table1 t1
inner join select * from table 2 t2 on t1.CountyCode[1] = Code[0]
Any one help me please.
Use this syntax:
select CountyCode, ContactPerson
from t1
inner join t2 on t1.CountyCode = t2.Code

How to join 3 tables in sql with or condition

I have 3 tables:
table1
inner join with table2; or:
inner join with table3
The query:
select table1.x
from table1 right outer join
table2
on table1.x = table2.x right outer join
table3
on table1.x = table3.x
but I can only see x values that are in both table2 and table3
Use left join, not right join, along with an appropriate filter condition:
select table1.x
from table1 left join
table2
on table1.x = table2.x left join
table3
on table1.x = table3.x
where table2.x is not null or table3.x is not null;
You might consider writing this using exists:
select t1.*
from table1 t1
where exists (select 1 from table2 t2 where t2.x = t1.x) or
exists (select 1 from table3 t3 where t3.x = t1.x);
That seems like a more natural way to implement your logic -- and you won't get duplicates when x is duplicated in table2 or table3.

Can we get result of left outer join using right outer join

Can we get the results of a left outer join using a right outer join?
Yes, you can do this. A right (outer) join is equivalent to a left (outer) join with the position of the tables switched.
Hence, the following query:
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
ON t1.col = t2.col
is equivalent to
SELECT *
FROM table2 t2
RIGHT JOIN table1 t1
ON t1.col = t2.col

t-sql table join

Is there any way I can do a join between two tables where the resulting table has only the columns of the left table without the need to discriminate all the columns names in the select?
You can do this:
Select LeftTable.*
From LeftTable
Inner Join RightTable
On LeftTable.Id = RightTable.Id
Select T.* from tbl1 T, tbl2 J
You mean something like
Select t1.id, t1.name, t1.age FROM t1 INNER JOIN t2 ON t1.id = t2.id
WHERE t2.Something = Something