Joining multiple tables by skipping On condition for few tables and join them alone - sql

I want to understand how we can join by skipping the On condition. Let me explain with example. If you notice in below query, there is no ON condition for T3 and I am just joining with that table to T4 table.
Question: How Data set will create and how that will combine to other other data set?
SELECT * FROM T1
INNER JOIN T2 ON T1.ID = T2.ID
INNER JOIN T3
LEFT JOIN T4 ON T3.ID = T4.ID
LEFT JOIN T5 ON T1.ID = T5.ID

Well, when there is no join relation, then you are basically performing a CROSS JOIN , your query is basically equivalent to :
SELECT * FROM T1
INNER JOIN T2 ON T1.ID = T2.ID
CROSS JOIN(SELECT * FROM T3
LEFT JOIN T4 ON T3.ID = T4.ID)
LEFT JOIN T5 ON T1.ID = T5.ID

Related

LEFT OUTER JOIN behaves like INNER JOIN [duplicate]

This question already has answers here:
Problems with INNER JOIN and LEFT/RIGHT OUTER JOIN
(5 answers)
Closed 2 years ago.
I have 3 tables: T1, T2, T3
I need to have all rows from T1 in result and if there are matching records in T2 and T3, then output them also.
So my query looks like
SELECT *
FROM T1
LEFT JOIN T2
ON T1.Id = T2.Id
INNER JOIN T3
ON T2.SecondId = T3.Id
But in result, I receive only records that have some records in T3.
Is it the same behavior as I would write
SELECT *
FROM T1
LEFT JOIN T2
ON T1.Id = T2.Id
WHERE T2.Value = 4
where LEFT JOIN behaves like INNER JOIN because of WHERE clause?
The syntax for what you probably want is:
SELECT *
FROM T1 LEFT JOIN
T2
ON T1.Id = T2.Id LEFT JOIN
T3
ON T2.SecondId = T3.Id
Without the second LEFT JOIN, the INNER JOIN filters out non-matches. That is because T2.SecondId will be NULL for those non-matches. This is the right approach; checking explicitly for NULLs has some edge cases that don't work.
For the second query:
SELECT *
FROM T1 LEFT JOIN
T2
ON T1.Id = T2.Id AND T2.Value = 4

Joining tbl1 to select statement twice with join to tbl2 that also joins to tbl3

I'm using SQL server manger.
I have 3 tables
I need a query that pulls t1 ands add an Origin Basin and a Destination Basin.
So far I have the following:
select T1.[Country (destination)], T3.AreaName
From T1
left outer join T2 on
T1.[Country (destination)] = T2.CountryName
inner join T3 on
T2.AreaID = T3.AreaID
inner join T3 on
T2.AreaID = T3.AreaID
Which returns:
Country | Area
However, I'm having trouble doing this for the second country column. I believe you use aliases. I've tried:
select (select AreaName
FROM T3
where T3.AreaID = T2.AreaID) as 'Area Imp',
(select AreaID
From T2
where T2.CountryName = T1.[Country (origin)]) as 'x',
(select AreaID
From T2
where T2.CountryName = T1.[Country (destination)]) as 'y'
FROM T1
But I can't get it to work.
This is what you need to do:
select t1.date, t1.country_destination, t1.country_origin, destination_area.AreaName as area_destination, origin_area.AreaName as area_origin
from t1 as t1 join t2 as destination on t1.country_destination = destination.countryname
join t2 as origin on t1.country_origin = origin.countryname
join t3 as destination_area on t2.areaid = destination_area.areaid
join t3 as origin_area on t2.areaid = origin_area.areaid
You will need to join with the same table twice, both for t2 and t3 so that you get the matching records for your needs.
It helps usually to put aliases that match the purpose of the join (in this case, destination and origin) when writing the query.
I think what you're trying to do is something like this:
select T1.*, T3dest.AreaName, T3orig.AreaName
From
T1
inner join
T2 T2dest on
T1.[Country (destination)] = T2dest.CountryName
inner join
T3 T3dest on
T2dest.AreaID = T3dest.AreaID
inner join
T2 T2orig on
T1.[Country (origin)] = T2orig.CountryName
inner join
T3 T3orig on
T2orig.AreaID = T3orig.AreaID
Note that I've switched to inner joins throughout, at the moment. If you do want left join semantics, you either need to use those for all of the joins to the T2 and T3 tables or you need to change the join order (so that the relevant T3 joins to the T2 tables occur before the attempted join with T1). It's not clear from the sample data if that's required, however.
Try this, You would still want to join on area id's
select T1.Date,T1.[Country (destination)], null [Country (origin)], T3.AreaName [AreaName(Destination)], null [AreaName(Origin)]
From T1
left outer join T2 on
T1.[Country (destination)] = T2.CountryName
inner join T3 on
T2.AreaID = T3.AreaID
union all
select T1.Date,null [Country (destination)], t1.[Country (origin)], Null [AreaName(Destination)], t3. [AreaName(Origin)]
From T1
left outer join T2 on
T1.[Country (Origin)] = T2.CountryName
inner join T3 on
T2.AreaID = T3.AreaID

How do I get the results of one JOIN and THEN feed those into a separate join in T-SQL?

I'm trying to JOIN 2 tables ON a key like
SELECT column1,column2
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.t2id = t2.id
Now, I have a 3rd table that has a Foreign Key with t2's id that I want to join... When I do
LEFT JOIN
Table3 t3 ON t3.t2id = --<-------------- This is where I'm lost
I don't know if I should do ON t3.t2id = t1.t2id OR ON t3.t2id = t2.id
What I need is the list of t2ids which are still in the picture after the first join. However, it seems as though if I specify either of the above, it will just pull ids from the original table before the first join?
To clarify one more time: I'm trying to essentially do a INNER JOIN of Table1 and Table2, get the resulting table, then get the t2ids of those results and feed them into a final join such that the final result contains all of Table3's rows as well as the data from the first join
You said: "final result contains all of Table3's rows as well as the data from the first join".
It means that you need
Table3 LEFT JOIN <previous results>
instead of
<previous results> LEFT JOIN Table3
The easiest way to write it is to use Common-Table Expressions:
WITH
CTE_InnerJoin
AS
(
SELECT column1, column2, t1.t2id
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.t2id = t2.id
)
SELECT
CTE_InnerJoin.column1
,CTE_InnerJoin.column2
,Table3....
FROM
Table3
LEFT JOIN CTE_InnerJoin ON CTE_InnerJoin.t2id = Table3.t2id
;
It doesn't matter what column you include in the CTE: t1.t2id or t2.id, the values in them are the same, because they are inner-joined together.
JOINs already do exactly what you want. A JOIN isn't always between two tables. Frequently, it's between the results of previous joins.
SELECT column1,column2
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.t2id = t2.id
LEFT JOIN
Table3 t3 ON t3.t2id = t2.id
At the point at which you're writing the final ON clause here, what you're joining is precisely the results of the previous INNER JOIN on the left and the table Table3 on the right. All of t1, t2 and t3 are in scope within the ON clause, but note that t1 and t2 are now both used as aliases into the same source of rows - the previous INNER JOIN.
As a further example, consider the "diamond join":
SELECT
*
FROM
t1
left join
t2
on
t1.a = t2.b
left join
t3
on
t1.c = t3.d
inner join
t4
on
t2.e = t4.f OR
t3.g = t4.h
This is a way of joining two tables (t1 and t4) based on two alternative joins. Note that in the final inner join, what is on the "left" is the result of already joining tables t1, t2 and t3.
Join the table having foreign key with
Try this....
SELECT column1,column2
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.t2id = t2.id
LEFT join Table3 t3 ON t2.id=t3.t2id
Or Like this.
SELECT t12.column1 ,
t12.column2 ,
t3.*
FROM (
--- INNER JOIN of Table1 and Table2, get the resulting table,
SELECT t1.column1 ,
t2.column2 ,
t1.t2id --- or t2.id doesn't matter because its inner join
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.t2id = t2.id
) T12
LEFT JOIN Table3 T3 ON t3.t2id = t1.t2id --- then get the t2ids of those results
--- and feed them into a final join
--- if you want to get all rows from Table3, Change LEFT JOIN Table3 T3 ON t3.t2id = T1.t2id
--- into RIGHT JOIN Table3 T3 ON t3.t2id = T1.t2id
try this
select t3.*, column1, column2
from
table1 t1 inner join table2 t2 on t1.t2id = t2.id
right outer join table3 t3 on t3.t2id = t2.id
equvalent to
select t3.*, column1, column2
from
table1 t1 inner join table2 t2 on t1.t2id = t2.id
right outer join table3 t3 on t3.t2id = t1.t2id
if you want all rows from table 3 and those matching rows from table1 inner joined to table2 then you can use this syntax:
select t3.*,
column1, column2
from table3 t3
left join table2 t2
inner join table1 t1
on t1.t2id = t2.id
on t3.t2id = t2.id

Join Query - If join table order changes

Query1:
select * from t1 inner join t2 on t1.id = t2.id
left join t4 on t2.id = t4.id
left join t3 on t2.id = t3.id
Query2:
select * from t1 inner join t2 on t1.id = t2.id
left join t3 on t2.id = t3.id
left join t4 on t2.id = t4.id
Result from Query1 and Query2 will be same or not?
You need to be careful when comparing joins with different join orders. If the joins are all inner joins, then the order doesn't matter. You examples have outer joins.
from t1 inner join
t2
on t1.id = t2.id left join
t4
on t2.id = t4.id left join
t3
on t2.id = t3.id
from t1 inner join
t2
on t1.id = t2.id left join
t3
on t2.id = t3.id left join
t4
on t2.id = t4.id
In this case, the conditions for the two joins are independent of each other. That is, t3 and t4 are only being compared to t2 which occurs earlier. The order of the joins is not going to make a difference to the result set.
When you are considering if the result set is the same, you need to consider the following (at least):
Are any of the join keys NULL?
Are columns being selected from all the tables?
Are there matches for all join conditions?
Have the joins changed from left to right?
Are there parentheses in the FROM clause?
There can be surprising (but subtle) differences for queries that look very similar.

Joining tables in sql server?

In SQL Server, I am joining three tables like below.
select t1.empid, t2.sales, t3.date
from table1 t1
left outer join table2 t2 on t1.empid = t2.empid
left outer join table3 t3 on t1.empid = t2.empid
and t2.id= t3.id
Is this correct, I use and condition, thank you.
if i write the proc: i am joing the table using left outer join
select wrh.empid
from Tbl_F_Weekly_Report_Header WRH
left outer join Tbl_Emp_Master_M EM on wrh.EmpId =em.EmpId
LEFT outer join Tbl_F_Emp_Position_M EPS on WRH.PositionCode = EPS.PositionCode
where EM [Tbl_Emp_Master_M] doesnot contain Positioncode
is it correct
Your LEFT OUTER JOIN on table3 is incorrect. You just need:
SELECT t1.empid, t2.sales, t3.date
FROM table1 AS t1
LEFT OUTER JOIN table2 AS t2 ON t1.empid = t2.empid
LEFT OUTER JOIN table3 AS t3 ON t2.id = t3.id
since you have already specified t1.empid = t2.empid above in the first LEFT OUTER JOIN
Your updated query:
SELECT wrh.empid
FROM Tbl_F_Weekly_Report_Header AS wrh
LEFT OUTER JOIN Tbl_Emp_Master_M AS em ON wrh.EmpId = em.EmpId
LEFT OUTER JOIN Tbl_F_Emp_Position_M AS eps ON wrh.PositionCode = eps.PositionCode
looks good, just make sure you include FROM (was originally missing from your question)
You just missed slect > select and t3 left outer join. You must use SQL server management studio to test your queries.
select
t1.empid,
t2.sales,
t3.date
from table1 t1
left outer join table2 t2 on t1.empid=t2.empid
left outer join table3 t3 on t2.id= t3.id
Regards
yes your sql statement is right. but you might try this:
select t1.empid, t2.sales, t3.date
from table1 t1
left outer join table2 t2 on t1.empid = t2.empid
inner join table3 t3 on t2.empid = t3.empid
or
select t1.empid, t2.sales, t3.date
from table1 t1
left outer join table2 t2 on t1.empid = t2.empid
left outer join table3 t3 on t2.empid = t3.empid