Inner join vs join [duplicate] - sql

Both these joins will give me the same results:
SELECT * FROM table JOIN otherTable ON table.ID = otherTable.FK
vs
SELECT * FROM table INNER JOIN otherTable ON table.ID = otherTable.FK
Is there any difference between the statements in performance or otherwise?
Does it differ between different SQL implementations?

They are functionally equivalent, but INNER JOIN can be a bit clearer to read, especially if the query has other join types (i.e. LEFT or RIGHT or CROSS) included in it.

No, there is no difference, pure syntactic sugar.

INNER JOIN = JOIN
INNER JOIN is the default if you don't specify the type when you use the word JOIN.
You can also use LEFT OUTER JOIN or RIGHT OUTER JOIN, in which case the word OUTER is optional, or you can specify CROSS JOIN.
OR
For an INNER JOIN, the syntax is:
SELECT ...
FROM TableA
[INNER] JOIN TableB
(In other words, the INNER keyword is optional--results are the same with or without it.)

Does it differ between different SQL implementations?
Yes, Microsoft Access doesn't allow just join. It requires inner join.

Similarly with OUTER JOINs, the word "OUTER" is optional. It's the LEFT or RIGHT keyword that makes the JOIN an "OUTER" JOIN.
However for some reason I always use "OUTER" as in LEFT OUTER JOIN and never LEFT JOIN, but I never use INNER JOIN, but rather I just use "JOIN":
SELECT ColA, ColB, ...
FROM MyTable AS T1
JOIN MyOtherTable AS T2
ON T2.ID = T1.ID
LEFT OUTER JOIN MyOptionalTable AS T3
ON T3.ID = T1.ID

As the other answers already state there is no difference in your example.
The relevant bit of grammar is documented here
<join_type> ::=
[ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ]
JOIN
Showing that all are optional. The page further clarifies that
INNER Specifies all matching pairs of rows are returned. Discards
unmatched rows from both tables. When no join type is specified, this
is the default.
The grammar does also indicate that there is one time where the INNER is required though. When specifying a join hint.
See the example below
CREATE TABLE T1(X INT);
CREATE TABLE T2(Y INT);
SELECT *
FROM T1
LOOP JOIN T2
ON X = Y;
SELECT *
FROM T1
INNER LOOP JOIN T2
ON X = Y;

Related

SQL semantic equivalence: {full, left, right} join on true = inner join on true?

Are the two SQL statements equivalent?
select * from tb1 {full, left, right} join tb2 on true
select * from tb1 inner join tb2 on true
In my opinion, I think these two statements are equivalent. But in PostgreSQL, it does not do the transformation. I do not know what other Databases do. Or is there any case I didn't consider?
These constructs are not the same:
select *
from tbl1 inner join
tbl2
on true;
and:
select *
from tbl1 left join
tbl2
on true;
Under most circumstances, both perform a CROSS JOIN. BUT, there is a difference when tbl2 has no rows.
When tbl2 has no rows, the INNER JOIN version returns no rows. The LEFT JOIN version returns rows from the first table with NULL values from the second.
RIGHT JOIN and FULL JOIN have analogous behavior with empty tables.

In Oracle, in regards to syntax - how do I convert the (+) syntax to modern conventional JOIN?

Suppose I have a FROM clause like so :
FROM
apps.po_requisition_lines_all prl,
apps.po_requisition_headers_all prha,
po.po_req_distributions_all prda,
po.po_distributions_all pda,
po.po_headers_all pha
where 1=1
and prl.requisition_header_id= prha.requisition_header_id
and prl.requisition_line_id= prda.requisition_line_id
and prda.distribution_id= pda.req_distribution_id(+)
and pha.po_header_id(+)=pda.po_header_id
Then how does this type of OUTER JOIN get converted if we want to use normal JOIN syntax ? thanks !
Without seeing the schema, I find it difficult but this should set you in the right direction:
FROM apps.po_requisition_lines_all prl
INNER JOIN apps.po_requisition_headers_all prha ON prl.requisition_header_id = prha.requisition_header_id
INNER JOIN po.po_req_distributions_all prda ON prda.requisition_line_id = prl.requisition_line_id
LEFT JOIN po.po_distributions_all pda ON prda.distribution_id = pda.req_distribution_id
-- I note from the example provided that this is a right join
-- Without seeing the schema, it looks to me as though it should be left
-- As I say say, without seeing the schema, I probably shouldn't pass comment
RIGHT JOIN po.po_headers_all pha ON pha.po_header_id = pda.po_header_id;
For an INNER JOIN you can just say JOIN although I think that explicitly saying INNER aids readability. I also note the example provided has WHERE 1=1 which is redundant.
The + is old version of Outer Joins, and it differs where the + comes after equality sign or before it, But now it's recommended to use Join keywords instead of +, about the + sign if it comes:
After =:
select * from t1, t2
where t1.id=t2.id(+)
This means Left Outer Join:
select * from t1
left outer join t2 on t1.id=t2.id
Before =:
select * from t1, t2
where t1.id(+)=t2.id
This means Right Outer Join:
select * from t1
Right outer join t2 on t1.id=t2.id
Without +:
select * from t1, t2
where t1.id=t2.id
This means Inner Join:
select * from t1
join t2 on t1.id=t2.id

SQL style question: INNER JOIN in FROM clause or WHERE clause?

If you are going to join multiple tables in a SQL query, where do you think is a better place to put the join statement: in the FROM clause or the WHERE clause?
If you are going to do it in the FROM clause, how do you format it so that it is clear and readable? (I'm talking about indents, newlines, whitespace in general.)
Are there any advantages/disadvantages to each?
I tend to use the FROM clause, or rather the JOIN clause itself, indenting like this (and using aliases):
SELECT t1.field1, t2.field2, t3.field3
FROM table1 t1
INNER JOIN table2 t2
ON t1.id1 = t2.id1
INNER JOIN table3 t3
ON t1.id1 = t3.id3
This keeps the join condition close to where the join is made. I find it easier to understand this way then trying to look through the WHERE clause to figure out what exactly is joined how.
When making OUTER JOINs (ANSI-89 or ANSI-92), filtration location matters because criteria specified in the ON clause is applied before the JOIN is made. Criteria against an OUTER JOINed table provided in the WHERE clause is applied after the JOIN is made. This can produce very different result sets.
In comparison, it doesn't matter for INNER JOINs if the criteria is provided in the ON or WHERE clauses -- the result will be the same. That said, I strive to keep the WHERE clause clean -- anything related to JOINed tables will be in their respective ON clause. Saves hunting through the WHERE clause, which is why ANSI-92 syntax is more readable.
I prefer the FROM clause if for no other reason that it distinguishes between filtering results (from a Cartesian product) merely between foreign key relationships and between a logical restriction. For example:
SELECT * FROM Products P JOIN ProductPricing PP ON P.Id = PP.ProductId
WHERE PP.Price > 10
As opposed to
SELECT * FROM Products P, ProductPricing PP
WHERE P.Id = PP.ProductID AND Price > 10
I can look at the first one and instantly know that the only logical restriction I'm placing is the price, as opposed to the implicit machinery of joining tables together on the relationship key.
I almost always use the ANSI 92 joins because it makes it clear that these conditions are for JOINING.
Typically I write it this way
FROM
foo f
INNER JOIN bar b
ON f.id = b.id
sometimes I write it this way when it trivial
FROM
foo f
INNER JOIN bar b ON f.id = b.id
INNER JOIN baz b2 ON b.id = b2.id
When its not trivial I do the first way
e.g.
FROM
foo f
INNER JOIN bar b
ON f.id = b.id
and b.type = 1
or
FROM
foo f
INNER JOIN (
SELECT max(date) date, id
FROM foo
GROUP BY
id) lastF
ON f.id = lastF.id
and f.date = lastF.Date
Or really the weird (not sure if I got the parens correctly but its supposed to be an LEFT join to table bar but bar needs an inner join to baz)
FROM
foo f
LEFT JOIN (bar b
INNER JOIN baz b2
ON b.id = b2.id
)ON f.id = b.id
You should put joins in Join clauses which means the From clause. A different question could be had about where to put filtering statements.
With respect to indenting, there are many styles. My preference is to indent related joins and keep main clauses like Select, From, Where, Group By, Having and Order By indented at the same level. In addition, I put each of these main attributes and the first line of an On clause on its own line.
Select ..
From Table1
Join Table2
On Table2.FK = Table1.PK
And Table2.OtherCol = '12345'
And Table2.OtherCol2 = 9876
Left Join (Table3
Join Table4
On Table4.FK = Table3.PK)
On Table3.FK = Table2.PK
Where ...
Group By ...
Having ...
Order By ...
Use the FROM clause to be compliant with ANSI-92 standards.
This:
select *
from a
inner join b
on a.id = b.id
where a.SomeColumn = 'x'
Not this:
select *
from a, b
where a.id = b.id
and a.SomeColumn = 'x'
I definitely always do my JOINS (of whatever type) in my FROM clause.
The way I indent them is this:
SELECT fields
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.t1_id
INNER JOIN table3 t3 ON t1.id = t3.t1_id
AND
t2.id = t3.t2_id
In fact, I'll generally go a step farther and move as much of my constraining logic from the WHERE clause to the FROM clause, because this (at least in MS SQL) front-loads the constraint, meaning that it reduces the size of the recordset sooner in the query construction (I've seen documentation that contradicts this, but my execution plans are invariably more efficient when I do it this way).
For example, if I wanted to only select things in the above query where t3.id = 3, you could but that in the WHERE clause, or you could do it this way:
SELECT fields
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.t1_id
INNER JOIN table3 t3 ON t1.id = t3.t1_id
AND
t2.id = t3.t2_id
AND
t3.id = 3
I personally find queries laid out in this way to be very readable and maintainable, but this is certainly a matter of personal preference, so YMMV.
Regardless, I hope this helps.
ANSI joins. I omit any optional keywords from the SQL as they only add noise to the equation. There's no such thing as a left inner join, is there? And by default, a simple join is an inner join, so there's no particular point to saying 'inner join'.
Then I column align things as much as possible.
The point being that a large complex SQL query can be very difficult to comprehend, so the more order that is imposed on it to make it more readable, the better. Any body looking at the query to fix, modify or tune it, needs to be able to answer a few things off right off the bat:
what tables/views are involved in the query?
what are the criteria for each join? What's the cardinality of each join?
what/how many columns are returned by the query
I like to write my queries so they look something like this:
select PatientID = rpt.ipatientid ,
EventDate = d.dEvent ,
Side = d.cSide ,
OutsideHistoryDate = convert(nchar, d.devent,112) ,
Outcome = p.cOvrClass ,
ProcedureType = cat.ctype ,
ProcedureCategoryMajor = cat.cmajor ,
ProcedureCategoryMinor = cat.cminor
from dbo.procrpt rpt
join dbo.procd d on d.iprocrptid = rpt.iprocrptid
join dbo.proclu lu on lu.iprocluid = d.iprocluid
join dbo.pathlgy p on p.iProcID = d.iprocid
left join dbo.proccat cat on cat.iproccatid = lu.iproccatid
where procrpt.ipatientid = #iPatientID

The different combinations of join are confusing, can someone boil it down a little?

Looking at JOIN's this weekend.
I was reading up on Join and seeing a ton of combinations of JOIN, LEFT, RIGHT, OUTER, FULL, INNER. I checked the MSDN docs and it looks like the only allowed combinations are in the form:
< join_type > ::=
[ INNER | { { LEFT | RIGHT | FULL } [ OUTER] } ]
[ < join_hint > ]
JOIN
so from that, I am figuring you can only get:
JOIN / INNER JOIN
LEFT JOIN / LEFT OUTER JOIN
RIGHT JOIN / RIGHT OUTER JOIN
FULL JOIN / FULL OUTER JOIN
Also, OUTER appears to be an optional keyword, so LEFT JOIN and LEFT OUTER JOIN are really the same. Is this correct? What's the difference between JOIN and FULL OUTER JOIN? I have seen a JOIN alone in a script, but haven't been able to break it down, because the query was a bit complicated.
There are only three kinds of join: CROSS, INNER, and OUTER.
Cross joins return every possible combination of rows from both tables, and aren't often used.
Inner joins only return rows where both tables match the join condition.
Outer joins pick one table as the "origin" table, and will always return all rows from that table. Any time there's no match in the other table, NULL values are supplied.
Within outer joins (and only outer joins) there are also three sub types: LEFT, RIGHT and FULL.
For Left joins, the first table is the origin table.
For Right joins the 2nd table is the origin table.
For Full joins, both tables are origin tables.
Because LEFT, RIGHT, and FULL only apply to OUTER joins, sometimes the OUTER keyword is omitted in favor of simply specifying which kind of outer join (ie, just "LEFT JOIN").
You appear to have more combinations than are supported:
<join_type> ::=
[ INNER | { { LEFT | RIGHT | FULL } [ OUTER] } ]
[ <join_hint> ]
JOIN
This says you can have:
JOIN INNER JOIN
LEFT JOIN LEFT OUTER JOIN
RIGHT JOIN RIGHT OUTER JOIN
FULL JOIN FULL OUTER JOIN
The keyword OUTER is optional, in other words. In the full SQL standard, you can also have a NATURAL JOIN or a CROSS JOIN. The keyword INNER is optional too; a plain 'JOIN' is an INNER JOIN.
Actually, the formatting of your answer led me into thinking you'd not understood properly; it ran INNER JOIN with LEFT JOIN (I'll fix that shortly if no-one else has).
A FULL JOIN is radically different from a plain (INNER) JOIN. The INNER JOIN is simply based on the specified criterion (specified by an ON clause or a USING clause). The LEFT OUTER JOIN consists of the rows of an INNER JOIN plus those rows from the left-hand table that are not joined with the right-hand table extended with NULL for each column in the right-hand table. This is sometimes called the 'left outer increment'. The RIGHT OUTER JOIN reverses the sense of the outer join (so there is a 'right outer increment'). The FULL JOIN consists of the union of the INNER JOIN and the left outer increment and the right outer increment. The result of a FULL JOIN does not have a primary key because there are, in general, nulls in every column.
These are all valid syntax that can go between table sources:
JOIN
INNER JOIN
LEFT JOIN
LEFT OUTER JOIN
RIGHT JOIN
RIGHT OUTER JOIN
FULL JOIN
FULL OUTER JOIN
Each requires a following ON clause.
You are correct that OUTER is optional, so RIGHT JOIN is the same as RIGHT OUTER JOIN, and likewise for LEFT and FULL. Also, INNER is optional if there is no , so JOIN is the same as INNER JOIN.
There is also CROSS JOIN, which is the same as a comma and has no ON clause. In other words,
FROM A CROSS JOIN B
and
FROM A,B
mean exactly the same thing.
The table operators JOIN and FULL OUTER JOIN are not at all the same. The table source
FROM A JOIN B ON <condition>
contains only rows for which <condition> is true. On the other hand, the table source
FROM A FULL OUTER JOIN B ON <condition>
contains rows for which <condition> is true along with all the additional rows that you'd get in either a LEFT OUTER JOIN or a RIGHT OUTER JOIN with the same ON clause.
The Wikipedia article on SQL join is quite clear and has lots of examples.

Difference between JOIN and INNER JOIN

Both these joins will give me the same results:
SELECT * FROM table JOIN otherTable ON table.ID = otherTable.FK
vs
SELECT * FROM table INNER JOIN otherTable ON table.ID = otherTable.FK
Is there any difference between the statements in performance or otherwise?
Does it differ between different SQL implementations?
They are functionally equivalent, but INNER JOIN can be a bit clearer to read, especially if the query has other join types (i.e. LEFT or RIGHT or CROSS) included in it.
No, there is no difference, pure syntactic sugar.
INNER JOIN = JOIN
INNER JOIN is the default if you don't specify the type when you use the word JOIN.
You can also use LEFT OUTER JOIN or RIGHT OUTER JOIN, in which case the word OUTER is optional, or you can specify CROSS JOIN.
OR
For an INNER JOIN, the syntax is:
SELECT ...
FROM TableA
[INNER] JOIN TableB
(In other words, the INNER keyword is optional--results are the same with or without it.)
Does it differ between different SQL implementations?
Yes, Microsoft Access doesn't allow just join. It requires inner join.
Similarly with OUTER JOINs, the word "OUTER" is optional. It's the LEFT or RIGHT keyword that makes the JOIN an "OUTER" JOIN.
However for some reason I always use "OUTER" as in LEFT OUTER JOIN and never LEFT JOIN, but I never use INNER JOIN, but rather I just use "JOIN":
SELECT ColA, ColB, ...
FROM MyTable AS T1
JOIN MyOtherTable AS T2
ON T2.ID = T1.ID
LEFT OUTER JOIN MyOptionalTable AS T3
ON T3.ID = T1.ID
As the other answers already state there is no difference in your example.
The relevant bit of grammar is documented here
<join_type> ::=
[ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ]
JOIN
Showing that all are optional. The page further clarifies that
INNER Specifies all matching pairs of rows are returned. Discards
unmatched rows from both tables. When no join type is specified, this
is the default.
The grammar does also indicate that there is one time where the INNER is required though. When specifying a join hint.
See the example below
CREATE TABLE T1(X INT);
CREATE TABLE T2(Y INT);
SELECT *
FROM T1
LOOP JOIN T2
ON X = Y;
SELECT *
FROM T1
INNER LOOP JOIN T2
ON X = Y;