Whether to use JOIN or not? [duplicate] - sql

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
INNER JOIN versus WHERE clause — any difference?
SQL JOIN: is there a difference between USING, ON or WHERE?
For example, I have this SQL statement:
SELECT *
FROM orders, inventory
WHERE orders.product = inventory.product
or
SELECT *
FROM orders
JOIN inventory
ON orders.product = inventory.product
What is the difference between these two?

They do exactly the same thing, but I'd recommend the second approach for readability and maintainability.
Using JOIN allows you to separate the conditions that define relationships between tables from conditions which are filters on the result set.
Using JOIN makes it easier to see if you are missing a join condition.
Using JOIN allows you to easily choose between INNER or OUTER JOIN. The comma syntax is equivalent to INNER JOIN (though some databases do have an extension to allow an outer join when using the first approach).
The most important is to be consistent about which you use. The comma syntax has different precedence from the JOIN keyword which can lead to confusing errors if you try to mix the two syntaxes in the same query. Because of point 3, it is easier to be consistent if you always use JOIN.

Inner join is ansi syntax, should be the preferred method.
Imagine how ugly this solution could get if you were to use the , with say many tables?
SELECT * FROM orders, inventory, products, logistics, accounting, materials, ...
Be kind to your future developers and anyone else looking at or maintaining this code use the JOIN syntax.

The comma (,) is equivalent to an CROSS JOIN. Using an explicit CROSS JOIN is more intuitive and recommended, as it can easily be changed to a LEFT JOIN, RIGHT JOIN, etc. Using CROSS JOIN is also ANSI-compliant.

They are functionally equivalent. The second one is 'newer'.

Related

SQL INNER JOIN implemented as implicit JOIN

Recently, I came across an SQL query which looked like this:
SELECT * FROM A, B WHERE A.NUM = B.NUM
To me, it seems as if this will return exactly the same as an INNER JOIN:
SELECT * FROM A INNER JOIN B ON A.NUM = B.NUM
Is there any sane reason why anyone would use a CROSS JOIN here? Edit: it seems as if most SQL applications will automatically use a INNER JOIN here.
The database is HSQLDB
The older syntax is a SQL antipattern. It should be replaced with an inner join anytime you see it. Part of why it is an antipattern is because it is impoosible to tell if a cross join was intended or not if the where clasues is ommitted. This causes many accidental cross joins espcially in complex queries. Further, in some databases (espcially Sql server) the implict outer joins do not work correctly and so people try to combine explicit and implict joins and get bad results without even realizing it. All in all it is a poor practice to even consider using an implict join.
Yes, your both statements will return the same result. Which one is to be used is a matter of taste. Every sane database system will use a join for both if possible, no sane optimizer will really use a cross product in the first case.
But note that your first syntax is not a cross join. It is just an implicit notation for a join which does not specify which kind of join to use. Instead, the optimizer must check the WHERE clauses to determine whether to use an inner join or a cross join: If an applicable join condition is found in the WHERE clause, this will result in an inner join. If no such clause is found it will result in a cross join. Since your first example specifies an applicable join condition (WHERE A.NUM = B.NUM) this results in an INNER JOIN and thus exactly equivalent to your second case.

What if i dont use Join Keyword in query?

I have a query where i am retrieving data from more than two tables. I am using the filter criteria in where clause but not using any join keyword
select
d.proc_code,
d.dos,
s.svc_type
from
claim_detail d, h_claim_hdr hh, car_svc s
where
d.bu_id="$inp_bu_id"
and
hh.bu_id="$inp_bu_id"
and
s.bu_id="$inp_bu_id"
and
d.audit_nbr="$inp_audit_nbr"
and
hh.audit_nbr="$inp_audit_nbr"
and
d.audit_nbr=hh.audit_nbr
and
s.car_svc_nbr=hh.aut_nbr
Is there a better way of writing this?
Although you are not using a JOIN keyword, your query does perform a JOIN.
A more "modern" way of writing your query (i.e. one following the ANSI SQL standard) would be as follows:
select
d.proc_code,
d.dos,
s.svc_type
from
claim_detail d
join
h_claim_hdr hh on d.audit_nbr=hh.audit_nbr
join
car_svc s on s.car_svc_nbr=hh.aut_nbr
where
d.bu_id="$inp_bu_id"
and
hh.bu_id="$inp_bu_id"
and
s.bu_id="$inp_bu_id"
and
d.audit_nbr="$inp_audit_nbr"
and
hh.audit_nbr="$inp_audit_nbr"
Note that this is simply a modern syntax. It expresses the same query, and it will not impact the performance.
Note that in order for a row to appear in the output of this query, the corresponding rows must exist in all three queries (i.e. it's an inner join). If you would like to return rows of claim_detail for which no h_claim_hdr and / or car_svc existed, use left outer join instead.
A comma in the from clause is essentially the same as a cross join. You really don't want to use a cross join, unless you really know what you are doing.
Proper join syntax has several advantages. The most important of which is the ability to express other types of joins easily and compatibly across databases.
Most people would probably find this version easier to follow and maintain:
select d.proc_code, d.dos, s.svc_type
from claim_detail d join
h_claim_hdr hh
on d.bu_id = hh.bu_id and d.audit_nbr = hh.audit_nbr
car_svc s
on d.bu_id = s.bu_id and s.car_svc_nbr = hh.aut_nbr
where d.bu_id = "$inp_bu_id"
d.audit_nbr = "$inp_audit_nbr";
Using the WHERE clause instead of the JOIN keyword is essentially a different syntax for doing a join. I believe it is called Theta syntax, where using the JOIN clause is called ANSI syntax.
I believe ANSI syntax is almost universally recommended, and some databases require ANSI syntax for outer JOINs.
If you do not use JOIN it will be an implicit inner join. As is in your example with the join criteria on your WHERE clause. So you could me missing records. Lets say you want all records from the first table even if there is not a corresponding record in the second. Your current code would only return the records from the first table that have a matching record in the second.
Joins

best practice: Oracle SQL Joins [duplicate]

This question already has answers here:
Condition within JOIN or WHERE
(10 answers)
Closed 9 years ago.
which example below is best practice for inner joins? the examples below are
pretty simple but, what if there are multiple tables involved?
which approach would you choose?
example queries:
simple
SELECT suppliers.supplier_id, suppliers.supplier_name, orders.order_date
FROM suppliers, orders
WHERE suppliers.supplier_id = orders.supplier_id;
using keyword INNER JOIN
SELECT suppliers.supplier_id, suppliers.supplier_name, orders.order_date
FROM suppliers
INNER JOIN orders
ON suppliers.supplier_id = orders.supplier_id;
Since 1992 ANSI recommends the JOIN notation, and regarding to readability this is what I would recommend using.
Everything has been said on this topic, but I will just remind that from a logical point of view it makes much more sense to separate the join conditions from the value filters for 2 reasons:
that's not the same thing at all
Oracle internally (and mysql probably too, even though I don't really know) first calculates intermediate recordsets and THEN, afterwards, applies the WHERE filters.
I'd recommend explicitly stating JOIN type and using ON clause.
But you need to use it correctly. In your example you forgot to include FROM clause and suppliers table.
SELECT suppliers.supplier_id,
suppliers.supplier_name,
orders.order_date
FROM suppliers s INNER JOIN
orders o ON s.supplier_id = o.supplier_id;
In terms of functionalities both WHERE AND JOINS are same..

Is there any difference between using innerjoin and writing all the tables directly in the from segment?

Do these two queries differ from each other?
Query 1:
SELECT * FROM Table1, Table2 WHERE Table1.Id = Table2.RefId
Query 2:
SELECT * FROM Table1 INNER JOIN Table2 ON Table1.Id = Table2.RefId
I analysed both methods and they clearly produced the same actual execution plans. Do you know any cases where using inner joins would work in a more efficient way. What is the real advantage of using inner joins rather than approaching the manner of "Query 1"?
The two statements you have provided are functionally equivalent to one another.
The variation is caused by differing SQL syntax standards.
For a really exciting read, you can lookup the various SQL standards by visiting the following Wikipedia link. On the right hand side are references and links to the various dialects/standards of SQL.
http://en.wikipedia.org/wiki/SQL
These SQL statements are synonymous, though specifying the INNER JOIN is the preferred method and follows ISO format. I prefer it as well because it limits the plumbing of joining the tables from your where clause and makes the goal of your query clearer.
These will result in an identical query plan, but the INNER JOIN, OUTER JOIN, CROSS JOIN keywords are prefered because they add clarity to the code.
While you have the ability to specifiy join hints using the keywords in the FROM clause, you can do more complicated joins in the WHERE clause. But otherwise, there will be no difference in query plan.
I will also add that the first syntax is much more subject to inadvertent cross joins as the queries get complicated. Further the left and right joins in this syntax do not work properly in SQL server and should never be used. Mixing the syntax when you add a left join can also cause problems where the query does not correctly return the results. The syntax in the first example has been outdated for 17 years, I see no reason to ever use it.
Query 1 is considered an old syntax style and its use is discouraged. You will run into problems with you use LEFT and Right joins using that syntax style. Also on SQL Server you can have problems mixing those two different syles together in queries that use view of different formats.
I have found a significant difference using the LEFT OUTER JOINS and putting the conditions on the joined table in the ON clause rather than the WHERE clause. Once you put a condition on the joined table in the WHERE clause, you defeat the left outer join.
When I was using Oracle, I used the archaic (+) after the joined table (with all conditions including join conditions in the WHERE clause)because that's what I knew. When we became a SQL Server shop, I was forced to use LEFT OUTER JOINs, and I found they didn't work as before until I discovered this behavior. Here's an example:
select NC.*,
IsNull(F.STRING_VAL, 'NONE') as USER_ID,
CO.TOTAL_AMT_ORDERED
from customer_order CO
INNER JOIN VTG_CO_NET_CHANGE NC
ON NC.CUST_ORDER_ID=CO.ID
LEFT OUTER JOIN USER_DEF_FIELDS F
ON F.DOCUMENT_ID = CO.ID and
F.PROGRAM_ID='VMORDENT' and
F.ID='UDF-0000072' and
F.DOCUMENT_ID is not null
where NC.acct_year=2017

inner joins in oracle

I was thinking about the syntax of inner joins in Oracle's SQL implementation and here is something that seems a bit inconsistent:
Let's say you have two relations loan(loan_number, branch_name, amount) and borrower(customer_name, loan_number). loan_number is the attribute common to both tables. Now, Oracle gives you two ways to express an inner join:
select *
from loan, borrower
where loan.loan_number = borrower.loan_number;
The above statement is equivalent to:
select *
from loan
inner join borrower
on loan.loan_number = borrower.loan_number;
However, when expressing a cross join there is only one way to express it:
select *
from loan, borrower;
The following statement is syntactically incorrect:
select *
from loan
inner join borrower;
This is invalid; Oracle expects the ON... part of the clause
Given that an inner join is just a cross join with a filter condition, do you guys think that this is an inconsistency in Oracle's SQL implementation? Am I missing something?
I'd be interested in hearing some other opinions. Thanks.
As David pointed out in his answer the syntax is:
select *
from loan cross join borrower;
Even though I was not aware of the above syntax I still think it's inconsistent. Having the cross join keyword in addition to allowing inner join without a join condition would be fine. A cross join is in fact an inner join without a join condition, why not express it as an inner join without the join condition?
I would agree that it is not consistent.
But I would argue that the Oracle implementation is a good thing:
when you do a join, you almost always want to include a filter condition, therefore the ON part is mandatory.
If you really, really don't want to have a filter condition (are you really sure?), you have to tell Oracle explicitly with CROSS JOIN sytax.
Makes a lot of sense to me not to be 100% consistent - it helps to avoid you mistakes.
SELECT *
FROM Loan
CROSS JOIN Borrower
No inconsistency.
Oracle also supports the natural join syntax, which joins two tables on the basis of shared column name(s). This would work in your case because both tables have a column called LOAN_NUMBER.
SELECT *
FROM Loan
NATURAL JOIN Borrower
Now, your same argument could be made in this case, that the use of the keyword natural is strictly unnecessary. But if we follow the logic we end up with a situation in which this statement could be either a cross join or a natural join, depending on the column names:
SELECT *
FROM Loan
JOIN Borrower
This is clearly undesirable, if only because renaming LOAN.LOAN_NUMBER to LOAN_ID would change the result set.
So, there's your answer: disambiguation.
This way of expressing inner joins:
select * from loan, borrower where loan.loan_number = borrower.loan_number;
is not recommended for almost 20 years. It was kept because it is simply a valid expression that happens to convey an inner join. I would concentrate in using the version closer to the current standard, minimizing the chances for misunderstanding and flat out errors.