What's the difference between Inner Join, Cross Join, and Left Outer Join? - inner-join

If an Inner Join can be thought of as a cross join and then getting the records that satisfy the condition, then a LEFT OUTER JOIN can be thought of as that, plus ONE record on the left table that doesn't satisfy the condition.
In other words, it is not a cross join that "goes easy" on the left records (even when the condition is not satisfied), because then the left record can appear many times (as many times as there are records in the right table).
So the LEFT OUTER JOIN is the Cross JOIN with the records satisfying the condition, plus ONE record from the LEFT TABLE that doesn't satisfy the condition?

I don't think it is correct to say a left outer join is: "the cross join with the records satsifying the condition and one record for the left table that doesn't satisy the condition".
An inner join without a condition is the same as a cross join. An inner join on x is the same as a cross join where x. But prefer the first as it is more explicit and harder to get wrong.
However with an outer join you don't always get the row "that doesn't satisfy the condition". The difference between a left outer join and an inner join is:
Inner join: If the join condition for a row in the left table fails for every row in the right table, you don't get that row.
Outer join: If the join condition for a row in the left table fails for every row in the right table, you get the row from the left table with NULLs for the columns in the right table.
You don't get both the rows that match and one row that doesn't - you either get the first situation or the second. Your statement seems to suggest that you can get both.

Related

How to write ON condition for CROSS JOIN in SQL SERVER

Unable to write Join condition using ON clause.
This is Working:
SELECT STUDENT.STD_NAME,CLASS_SUBJECT.SUB_NAME
FROM STUDENT CROSS JOIN CLASS_SUBJECT
WHERE STUDENT.CLS_ID=CLASS_SUBJECT.CLS_ID
This is not working:
SELECT STUDENT.STD_NAME,CLASS_SUBJECT.SUB_NAME
FROM STUDENT CROSS JOIN CLASS_SUBJECT ON STUDENT.CLS_ID=CLASS_SUBJECT.CLS_ID
CROSS JOIN does not use an ON clause. It produces a cartesian product, matching all records from both tables. There are only very rare cases where you actually want this.
If you want conditional record matching between tables (for example where key values match), you should use INNER JOIN or one of the OUTER JOIN variants (LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN).
Combining CROSS JOIN with a WHERE clause for conditional record matching is possible, but using INNER JOIN is recommended in such cases.

SQL Server replaces LEFT JOIN for LEFT OUTER JOIN in view query

I need to use a LEFT JOIN in a View however SQL Server replaces LEFT JOIN for LEFT OUTER JOIN every time I save my view.
When trying to use LEFT INNER JOIN explicitly I get the error "Incorrect syntax near word 'INNER'". What is more when I want to create an index for the view I get the error "Cannot add clustered index to views using OUTER JOINS".
It's maddening, and ideas why this could be happening?
So when I try to create an index for the view I get the message I used an outer join though I didn't.
You are getting the joins confused and keep in mind there are different ways of writing joins. What you're looking for is a LEFT OUTER JOIN(OUTER is an optional). There is no LEFT INNER JOIN.
There are three major types of joins.
Type 1: INNER JOIN - only where both tables match
1.) INNER JOIN aka JOIN
Type 2: OUTER JOINS where either one or both tables match
1.) LEFT OUTER JOIN aka LEFT JOIN
2.) RIGHT OUTER JOIN aka RIGHT JOIN
3.) FULL OUTER JOIN aka FULL JOIN
Type 3: CROSS JOIN - Cartesian product(all possible combos of each table)
1.) Cross Join
Here's a graphic showing how each works:

SQL Server speed: left outer join vs inner join

In theory, why would inner join work remarkably faster then left outer join given the fact that both queries return same result set. I had a query which would take long time to describe, but this is what I saw changing single join: left outer join - 6 sec, inner join - 0 sec (the rest of the query is the same). Result set: the same
Actually depending on the data, left outer join and inner join would not return the same results..most likely left outer join will have more result and again depends on the data..
I'd be worried if I changed a left join to an inner join and the results were not different. I would suspect that you have a condition on the left side of the table in the where clause effectively (and probably incorrectly) turning it into an inner join.
Something like:
select *
from table1 t1
left join table2 t2 on t1.myid = t2.myid
where t2.somefield = 'something'
Which is not the same thing as
select *
from table1 t1
left join table2 t2
on t1.myid = t2.myid and t2.somefield = 'something'
So first I would be worried that my query was incorrect to begin with, then I would worry about performance. An inner join is NOT a performance enhancement for a Left Join, they mean two different things and should return different results unless you have a table where there will always be a match for every record. In this case you change to an inner join because the other is incorrect not to improve performance.
My best guess as to the reason the left join takes longer is that it is joining to many more rows that then get filtered out by the where clause. But that is just a wild guess. To know you need to look at the Execution plans.

Multiple Joins in TSQL

I am trying to JOIN multiple tables to the same value in a table. So I have the table ActivityPartyBase and it has a column PartyId. I want to join COntactId in ContactBase table to PartyId and AccountId in AccountBase table to PartyId. This is the code I am using and it doesn't return anything. If I only join one it works. Any ideas?
SELECT DISTINCT Appointment.ScheduledStart, ActivityPartyBase.ActivityId
, Appointment.ActivityId AS Expr1, ActivityPartyBase.ScheduledStart AS Expr2
, Appointment.Subject, ActivityPartyBase.PartyId, ContactBase.ContactId
, ContactBase.FullName
FROM Appointment
INNER JOIN ActivityPartyBase
ON Appointment.ActivityId = ActivityPartyBase.ActivityId
INNER JOIN AccountBase ON ActivityPartyBase.PartyId = AccountBase.AccountId
LEFT OUTER JOIN ContactBase ON ActivityPartyBase.PartyId = ContactBase.ContactId
ORDER BY Appointment.ScheduledStart DESC
Your inner joins are filtering out results because there is no corresponding record on the joined table. I've always found the easiest way to debug is to "Select *" and use all LEFT JOINs. This will show you everything in your tables that relates to your main table; you should be able to look at your data and figure out what table is missing a record easily at that point.
To confirm that this is just a naming convention mismatch,
INNER JOIN AccountBase ON ActivityPartyBase.PartyId = AccountBase.AccountId
Are PartyID and AccountId the PK/FK?
Given this...
FROM Appointment
INNER JOIN ActivityPartyBase ON Appointment.ActivityId = ActivityPartyBase.ActivityId
INNER JOIN AccountBase ON ActivityPartyBase.PartyId = AccountBase.AccountId
LEFT OUTER JOIN ContactBase ON ActivityPartyBase.PartyId = ContactBase.ContactId
... you state this works (?) ...
FROM Appointment
INNER JOIN ActivityPartyBase ON Appointment.ActivityId = ActivityPartyBase.ActivityId
/* INNER JOIN AccountBase ON ActivityPartyBase.PartyId = AccountBase.AccountId */
/* LEFT OUTER JOIN ContactBase ON ActivityPartyBase.PartyId = ContactBase.ContactId */
Since the LEFT OUTER JOIN won't explicitly cause no results, that won't be your problem. Since the INNER JOIN will cause what you're seeing, we can only deduce that the join condition is incorrect.
In other words, ActivityPartyBase.PartyId is not equal to AccountBase.AccountID.
Are you sure there is data in all three tables in the inner join?
I'm guessing one of your INNER JOINs isn't picking up any data. Start with all 3 joins, then take out one of the joins at a time see which one breaks it. Then look at your join conditions and see which column isn't returning a record.
SOunds to me as if the tables are mutually exclusive. If it is ione table it is not inthe other (poor design). Try left joins to both tables.

LEFT JOIN vs. LEFT OUTER JOIN in SQL Server

What is the difference between LEFT JOIN and LEFT OUTER JOIN?
As per the documentation: FROM (Transact-SQL):
<join_type> ::=
[ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ]
JOIN
The keyword OUTER is marked as optional (enclosed in square brackets). In this specific case, whether you specify OUTER or not makes no difference. Note that while the other elements of the join clause is also marked as optional, leaving them out will make a difference.
For instance, the entire type-part of the JOIN clause is optional, in which case the default is INNER if you just specify JOIN. In other words, this is legal:
SELECT *
FROM A JOIN B ON A.X = B.Y
Here's a list of equivalent syntaxes:
A LEFT JOIN B A LEFT OUTER JOIN B
A RIGHT JOIN B A RIGHT OUTER JOIN B
A FULL JOIN B A FULL OUTER JOIN B
A INNER JOIN B A JOIN B
Also take a look at the answer I left on this other SO question: SQL left join vs multiple tables on FROM line?.
To answer your question there is no difference between LEFT JOIN
and LEFT OUTER JOIN, they are exactly same that said...
At the top level there are mainly 3 types of joins:
INNER
OUTER
CROSS
INNER JOIN - fetches data if present in both the tables.
OUTER JOIN are of 3 types:
LEFT OUTER JOIN - fetches data if present in the left table.
RIGHT OUTER JOIN - fetches data if present in the right table.
FULL OUTER JOIN - fetches data if present in either of the two tables.
CROSS JOIN, as the name suggests, does [n X m] that joins everything to everything.
Similar to scenario where we simply lists the tables for joining (in the FROM clause of the SELECT statement), using commas to separate them.
Points to be noted:
If you just mention JOIN then by default it is a INNER JOIN.
An OUTER join has to be LEFT | RIGHT | FULL you can not simply say OUTER JOIN.
You can drop OUTER keyword and just say LEFT JOIN or RIGHT JOIN or FULL JOIN.
For those who want to visualise these in a better way, please go to this link:
A Visual Explanation of SQL Joins
What is the difference between left join and left outer join?
Nothing. LEFT JOIN and LEFT OUTER JOIN are equivalent.
Left Join and Left Outer Join are one and the same. The former is the shorthand for the latter. The same can be said about the Right Join and Right Outer Join relationship. The demonstration will illustrate the equality. Working examples of each query have been provided via SQL Fiddle. This tool will allow for hands on manipulation of the query.
Given
Left Join and Left Outer Join
Results
Right Join and Right Outer Join
Results
I'm a PostgreSQL DBA, as far as I could understand the difference between outer or not outer joins difference is a topic that has considerable discussion all around the internet. Until today I never saw a difference between those two; So I went further and I try to find the difference between those.
At the end I read the whole documentation about it and I found the answer for this,
So if you look on documentation (at least in PostgreSQL) you can find this phrase:
"The words INNER and OUTER are optional in all forms. INNER is the default; LEFT, RIGHT, and FULL imply an outer join."
In another words,
LEFT JOIN and LEFT OUTER JOIN ARE THE SAME
RIGHT JOIN and RIGHT OUTER JOIN ARE THE SAME
I hope it can be a contribute for those who are still trying to find the answer.
I find it easier to think of Joins in the following order:
CROSS JOIN - a Cartesian product of both tables. ALL joins begin here
INNER JOIN - a CROSS JOIN with a filter added.
OUTER JOIN - an INNER JOIN with missing elements (from either LEFT or RIGHT table)
added afterward.
Until I figured out this (relatively) simple model, JOINS were always a bit more of a black art. Now they make perfect sense.
Hope this helps more than it confuses.
To answer your question
In Sql Server joins syntax OUTER is optional
It is mentioned in msdn article : https://msdn.microsoft.com/en-us/library/ms177634(v=sql.130).aspx
So following list shows join equivalent syntaxes with and without OUTER
LEFT OUTER JOIN => LEFT JOIN
RIGHT OUTER JOIN => RIGHT JOIN
FULL OUTER JOIN => FULL JOIN
Other equivalent syntaxes
INNER JOIN => JOIN
CROSS JOIN => ,
Strongly Recommend Dotnet Mob Artice : Joins in Sql Server
Why are LEFT/RIGHT and LEFT OUTER/RIGHT OUTER the same? Let's explain why this vocabulary.
Understand that LEFT and RIGHT joins are specific cases of the OUTER join, and therefore couldn't be anything else than OUTER LEFT/OUTER RIGHT. The OUTER join is also called FULL OUTER as opposed to LEFT and RIGHT joins that are PARTIAL results of the OUTER join. Indeed:
Table A | Table B Table A | Table B Table A | Table B Table A | Table B
1 | 5 1 | 1 1 | 1 1 | 1
2 | 1 2 | 2 2 | 2 2 | 2
3 | 6 3 | null 3 | null - | -
4 | 2 4 | null 4 | null - | -
null | 5 - | - null | 5
null | 6 - | - null | 6
OUTER JOIN (FULL) LEFT OUTER (partial) RIGHT OUTER (partial)
It is now clear why those operations have aliases, as well as it is clear only 3 cases exist: INNER, OUTER, CROSS. With two sub-cases for the OUTER.
The vocabulary, the way teachers explain this, as well as some answers above, often make it looks like there are lots of different types of join. But it's actually very simple.
There are only 3 joins:
A) Cross Join = Cartesian (E.g: Table A, Table B)
B) Inner Join = JOIN (E.g: Table A Join/Inner Join Table
B)
C) Outer join:
There are three type of outer join
Left Outer Join = Left Join
Right Outer Join = Right Join
Full Outer Join = Full Join
There are mainly three types of JOIN
Inner: fetches data, that are present in both tables
Only JOIN means INNER JOIN
Outer: are of three types
LEFT OUTER - - fetches data present only in left table & matching condition
RIGHT OUTER - - fetches data present only in right table & matching condition
FULL OUTER - - fetches data present any or both table
(LEFT or RIGHT or FULL) OUTER JOIN can be written w/o writing "OUTER"
Cross Join: joins everything to everything
Syntactic sugar, makes it more obvious to the casual reader that the join isn't an inner one.
Just in the context of this question, I want to post the 2 'APPLY' operators as well:
JOINS:
INNER JOIN = JOIN
OUTER JOIN
LEFT OUTER JOIN = LEFT JOIN
RIGHT OUTER JOIN = RIGHT JOIN
FULL OUTER JOIN = FULL JOIN
CROSS JOIN
SELF-JOIN: This is not exactly a separate type of join. This is basically joining a table to itself using one of the above joins. But I felt it is worth mentioning in the context JOIN discussions as you will hear this term from many in the SQL Developer community.
APPLY:
CROSS APPLY -- Similar to INNER JOIN (But has added advantage of being able to compute something in the Right table for each row of the Left table and would return only the matching rows)
OUTER APPLY -- Similar to LEFT OUTER JOIN (But has added advantage of being able to compute something in the Right table for each row of the Left table and would return all the rows from the Left table irrespective of a match on the Right table)
https://www.mssqltips.com/sqlservertip/1958/sql-server-cross-apply-and-outer-apply/
https://sqlhints.com/2016/10/23/outer-apply-in-sql-server/
Real life example, when to use OUTER / CROSS APPLY in SQL
I find APPLY operator very beneficial as they give better performance than having to do the same computation in a subquery. They are also replacement of many Analytical functions in older versions of SQL Server. That is why I believe that after being comfortable with JOINS, one SQL developer should try to learn the APPLY operators next.

Resources