when writing a query using any joins does it matter which side the On is based
Example
select * from customer C
join Address ON A.CustomerId=C.CustomerID -- would it make a difference if I did ON C.CustomerId=A.CustomerID
where c.CustomerId=1
What about left or right joins?
thanks a lot
No. You are still joining the two tables. I would consider it best practice to put the joining table on the right handside.
Does it matter? No.
LEFT vs RIGHT - depends on the results you want.
SELECT * FROM A LEFT JOIN B ON A.aid=b.aid
will give you all results from A whether or not they have a matching record in B - so the fields returned from B will be NULL for records where B doesn't match.
SELECT * FROM A RIGHT JOIN B ON ...
will give you all records from B and the possibility of null values in the fields provided by A...
Equality is a commutative operation. A=B is the same as B=A, so the specific ordering in the JOIN clause is irrelevant.
If you were doing inequality tests, < and >, then the ordering would matter. B>A is not the same A>B (and ditto for A<B and B<A)
Related
What will happen in an Oracle SQL join if I don't use all the tables in the WHERE clause that were mentioned in the FROM clause?
Example:
SELECT A.*
FROM A, B, C, D
WHERE A.col1 = B.col1;
Here I didn't use the C and D tables in the WHERE clause, even though I mentioned them in FROM. Is this OK? Are there any adverse performance issues?
It is poor practice to use that syntax at all. The FROM A,B,C,D syntax has been obsolete since 1992... more than 30 YEARS now. There's no excuse anymore. Instead, every join should always use the JOIN keyword, and specify any join conditions in the ON clause. The better way to write the query looks like this:
SELECT A.*
FROM A
INNER JOIN B ON A.col1 = B.col1
CROSS JOIN C
CROSS JOIN D;
Now we can also see what happens in the question. The query will still run if you fail to specify any conditions for certain tables, but it has the effect of using a CROSS JOIN: the results will include every possible combination of rows from every included relation (where the "A,B" part counts as one relation). If each of the three parts of those joins (A&B, C, D) have just 100 rows, the result set will have 1,000,000 rows (100 * 100 * 100). This is rarely going to give the results you expect or intend, and it's especially suspect when the SELECT clause isn't looking at any of the fields from the uncorrelated tables.
Any table lacking join definition will result in a Cartesian product - every row in the intermediate rowset before the join will match every row in the target table. So if you have 10,000 rows and it joins without any join predicate to a table of 10,000 rows, you will get 100,000,000 rows as a result. There are only a few rare circumstances where this is what you want. At very large volumes it can cause havoc for the database, and DBAs are likely to lock your account.
If you don't want to use a table, exclude it entirely from your SQL. If you can't for reason due to some constraint we don't know about, then include the proper join predicates to every table in your WHERE clause and simply don't list any of their columns in your SELECT clause. If there's a cost to the join and you don't need anything from it and again for some very strange reason can't leave the table out completely from your SQL (this does occasionally happen in reusable code), then you can disable the joins by making the predicates always false. Remember to use outer joins if you do this.
Native Oracle method:
WITH data AS (SELECT ROWNUM col FROM dual CONNECT BY LEVEL < 10) -- test data
SELECT A.*
FROM data a,
data b,
data c,
data d
WHERE a.col = b.col
AND DECODE('Y','Y',NULL,a.col) = c.col(+)
AND DECODE('Y','Y',NULL,a.col) = d.col(+)
ANSI style:
WITH data AS (SELECT ROWNUM col FROM dual CONNECT BY LEVEL < 10)
SELECT A.*
FROM data a
INNER JOIN data b ON a.col = b.col
LEFT OUTER JOIN data c ON DECODE('Y','Y',NULL,a.col) = b.col
LEFT OUTER JOIN data d ON DECODE('Y','Y',NULL,a.col) = d.col
You can plug in a variable for the first Y that you set to Y or N (e.g. var_disable_join). This will bypass the join and avoid both the associated performance penalty and the Cartesian product effect. But again, I want to reiterate, this is an advanced hack and is probably NOT what you need. Simply leaving out the unwanted tables it the right approach 95% of the time.
If I got more then one join and in the second join I use left join.
by using this clause its going to take all the data from the two first tables or only from the second table.
Thanks
Join is just a method to connect different tables. Theoretically (not computationally), there's no limit on the number of joins you used on a query.
Keep in mind that the order of joins are important once you started to use something other than inner joins. For example, a LEFT JOIN b is not equivalent to b LEFT JOIN a.
With that being said, when you have more than one join, the result should be interpreted carefully.
Consider
SELECT a.id,b.name,c.department
FROM
a INNER JOIN b on a.id = b.id
LEFT JOIN c on a.id = c.id
The resulting table would consist of all id that is present in both a and b, and return NULL if a department is not present for those id.
So to answer your question, joins consider all your data in the query. However, the output table depends on the joins you used. If there are still confusion, you can refer to this question which addressed a similar thing.
Can we achieve desired results of joining tables by executing joins in whatever order? Suppose we want to left join two tables A and B (order AB). We can get the same results with right join of B and A (BA).
What about 3 tables ABC. Can we get whatever results by only changing order and joins types? For example A left join B inner join C. Can we get it with BAC order? What about if we have 4 or more tables?
Update.
The question Does the join order matter in SQL? is about inner join type. Agreed that then the order of join doesn't matter. The answer provided in that question does not answer my question whether it is possible to get desired results of joining tables with whatever original join types (join types here) by choosing whatever order of tables we like, and achieve this goal only by manipulating with join types.
In an inner join, the ordering of the tables in the join doesn't matter - the same rows will make up the result set regardless of the order they are in the join statement.
In either a left or right outer join, the order DOES matter. In A left join B, your result set will contain one row for every record in table A, irrespective of whether there is a matching row in table B. If there are non matching rows, this is likely to be a different result set to B left join A.
In a full outer join, the order again doesn't matter - rows will be produced for each row in each joined table no matter what their order.
Regarding A left join B vs B right join A - these will produce the same results. In simple cases with 2 tables, swapping the tables and changing the direction of the outer join will result in the same result set.
This will also apply to 3 or more tables if all of the outer joins are in the same direction - A left join B left join C will give the same set of results as C right join B right join A.
If you start mixing left and right joins, then you will need to start being more careful. There will almost always be a way to make an equivalent query with re-ordered tables, but at that point sub-queries or bracketing off expressions might be the best way to clarify what you are doing.
As another commenter states, using whatever makes your purpose most clear is usually the best option. The ordering of the tables in your query should make little or no difference performance wise, as the query optimiser should work this out (although the only way to be sure of this would be to check the execution plans for each option with your own queries and data).
I want to join a couple of tables but filter a particular type from 'A' table. Which is the better query from the following two queries (is there a better approach?) or is there no difference cause of query optimizer ?
When filter condition is given in 'WHERE' clause:
SELECT .. FROM A a JOIN B b ON a.id=b.id JOIN C c on a.id = c.id...<other joins>...WHERE a.col='SOME_VAL';
The filter condition is given inside 'ON':
SELECT .. FROM A a JOIN B b ON a.id=b.id AND a.col='SOME_VAL' JOIN C c on a.id = c.id...<other joins>
With INNER JOINs there is no resulting performance difference, which you can check using EXPLAIN (both forms of your query should yield the same plan).
The benefit of using the WHERE clause can often be readability. When combined with a multi-line layout. (I strongly recommend Not keeping all your SQL as one long line.)
SELECT
stuff
FROM
foo
INNER JOIN
bar
ON (join predicates here)
WHERE
(static filters here)
The reason it becomes easier to read (and maintain) is that the join predicates now expressly only describe the Relationship between the tables. The query still runs correctly without the WHERE clause, but returns a larger set.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it better to do an equi join in the from clause or where clause
I have following two SQL queries. Can you please explain me the differences between these two ?
QUERY: 1
SELECT a.*, b.*
FROM Table1 a
INNER JOIN Table2 b
ON a.id = b.id
AND a.col = 'value'
QUERY: 2
SELECT a.*, b.*
FROM Table1 a
INNER JOIN Table2 b
ON a.id = b.id
WHERE a.col = 'value'
Thanks
Nothing unless case sensitivity is turned on on the database
For an INNER JOIN, filtering on the JOIN condition vs filtering in the WHERE clause should give identical results.
If this were an OUTER JOIN, the results would be different since the first one pre-filters the results in the source table before the JOIN condition.
in this particular case it's the same result, but it's not the same thing.
the WHERE applies to the whole select, while the ON ... AND is only for the inner join (actually probably the same thing, but not for outer joins)
Yes, everything is pretty much the same. Case sensitive database will return error if your ID fields is not spelled correctly.
The difference is purely stylistic. Personally, I like to put the clauses that are key to performing the table joins up under the 'JOIN ... ON a=b' section, and put the clauses that have to do with my specific query filtering under the "WHERE" clause. There is no technical reason to do it one way or the other though, so long as you're talking about inner joins.