MySQL statement using OUTER JOIN vs using WHERE to set conditions - mysql

For the statements with INNER JOIN:
SELECT column(s) FROM table1
INNER JOIN table2 ON condition(s)
...
INNER JOIN tableN ON condition(s);
I can write an equivalent statement with this:
SELECT column(s) FROM table1, table2, ..., tableN WHERE condition(s);
notice how I use WHERE to set my conditions in the second statement.
Question: can I write equivalent statements using WHERE to set my conditions for any OUTER (LEFT/RIGHT) JOIN statements as well?

can I write equivalent statements using WHERE to set my conditions for any OUTER (LEFT/RIGHT) JOIN statements as well?
No, not in ANSI SQL or MySQL. Some other databases have their own syntax that was used before the ANSI JOIN syntax was accepted. For example in Oracle 8:
WHERE table1.id=table2.thing (+)
But today the ANSI JOIN syntax should generally be preferred for both kinds of join.

I am no MYSQL expert, but in oracle the syntax for an outer join in a where condition is where t1.id += t2.id

From the MySQL 5.0 Reference Manual :
"INNER JOIN and, (comma) are semantically equivalent in the absence of a join condition"
So to me, that would read that a comma implies an INNER JOIN.
I recommend you use ANSI join syntax for greater clarity and portability.

SELECT ...
FROM table1 t1
RIGHT OUTER JOIN table2 t2 ON (t1.x = t2.y AND somecondition)

In Sybase you can use table1.field1 = table2.field1 (left outer) = right outer

Related

Why does this "nested join" works with PDO but not with MySql cli?

I don't understand why this query works and what it actually means. It should be noted that this query works when using PDO but doesn't through Mysql cli or even phpmyadmin.
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN table 1
INNER JOIN table2
ON table2.table1_id = table1.id
ON table1.account_id = someTable.account_id
No errors are thrown and, even weirder, I actually have results that are coherent with what the query is supposed to do.
This is valid SQL syntax, assuming you have just taken a snippet from the FROM clause. It is interpreted as:
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN
(table1 INNER JOIN
table2 bbm
ON table2.table1_id = table1.id
)
ON table1.account_id = table2.account_id
That said, this is really arcane, because the alias renames table2 to bbm, which is not used. The ON conditions are only referring to earlier tables. The result is some strange form of CROSS JOIN.
That you can nest JOINs this way should -- in my opinion -- be merely viewed as an amusement. Don't nest JOINs. Each JOIN should be followed by its very own ON clause, before the next table/subquery reference. Nesting joins makes the code is harder to understand. It can introduce errors (which I think happened in this case). There can also be subtle edge cases where it is a little challenging to figure out what is happening.
There are two syntax variations in Standard SQL for writing multiple joins, the common one:
a join b on ... join c on ... join d on ...
and the strange one:
a join b join c join d on ... on ... on ...
In both cases the first ON is processed first, which means the strange syntax joins the first table in the last ON and the last table in the first ON, which is really hard to follow. That's why almost nobody is using it (but some tools might create it)
To change your strange
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN table1
INNER JOIN table2 bbm
ON table2.table1_id = table1.id
ON table1.account_id = someTable.account_id
to the common one move the last ON after the first join:
SELECT table1.something, table2.something
FROM someTable
LEFT JOIN table1
ON table1.account_id = someTable.account_id
INNER JOIN table2 bbm
ON table2.table1_id = table1.id

(+) function in PLSQL

I'm now dealing with PLSQL developer, which is my very first time. And I find this kind of query
select * from tableA, tableB
where tableA.field1 = tableB.field1(+)
I'm wondering the function of the (+) in the query. Could you guys be so kind to explain it ?
where tableA.field1 = tableB.field1(+)
This is the old syntax for an outer join, adopted by Oracle, and made redundant when ANSI actually standardised the SQL language. Oracle themselves now suggest you use outer join in preference to this old syntax (from the link below):
Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator.
See this entry in the Oracle docs for more detail.
This is Oracle SQL OUTER JOIN syntax
It can be interpreted as
select * from tableA
OUTER JOIN tableB ON tableA.field1 = tableB.field1
From the oracle documentation:
(+) Indicates that the preceding column is the outer join column in a join.
It can be used as
select * from tableA right outer join tableB where tableA.field1 = tableB.field1
(+)operator indicates that it will return all the rows from the right table(matching and non matching) both rows from the right table.
And matching rows are returned from the left table.
If rows are not matching from the right table then it returns null.
+ is used to retrive the mathced and unmached records from the table.
example:
table A and table B
if you are using like A.column1=B.column1(+)
it retrives the unmached records from table A and its called as left outer join.
That's Oracle specific notation for a LEFT OUTER JOIN
Exemple :
select ...
from a,b
where a.id=b.id(+)
The query would be re-written
SELECT ...
FROM a
LEFT JOIN b ON b.id = a.id

MySQL JOIN behind the scenes

I remember reading somewhere / being told / inventing a rumor (^_^) that the two following queries are the same behind the scenes in MySQL servers:
SELECT *
FROM a
JOIN b
ON a.id = b.id
and
SELECT *
FROM a, b
WHERE a.id = b.id
Is it true? If so, is one better than the alternate in other terms? (such as parsing efficiency or standard compliance)
It is in fact true. The first query is according the SQL-89 standard and the second is according to SQL-92.
The SQL-92 standard introduced INNER JOIN .. ON and OUTER JOIN .. ON in order to replace the more complex(?) syntax of SQL-89.
An outer join in SQL-89 would be:
SELECT ...
FROM t1, t2
WHERE t1.id *= t2.id
where in SQL-92 it would be
FROM t1 OUTER JOIN t2 ON t1.id = t2.id
I did prefer SQL-89 over SQL-92 for a long while, but I think SQL Server 2008 compability removed the support for SQL-89 join syntax.
yep, these are identical. But it's not something specific to Mysql - it's just a different joining styles. The one you wrote on top is newer and preffered one

Teradata equivalent of MySQL's USING

My question is quite similar to this one, but in Teradata:
SQL Server equivalent of MySQL's USING
Is there any equivalent shortcut to this query?
SELECT *
FROM t1
JOIN t2
ON (t1.column = t2.column)
No. The closest thing you can do with a natural join is:
SELECT
FROM T1, T2
WHERE t1.column = t2.column;
Yes. It's ANSI JOIN syntax. For example:
SELECT
*
FROM T1
INNER JOIN T2 ON T1.column = T2.column
;
For a multiple column join criteria, do the following:
SELECT
*
FROM T1
INNER JOIN T2 ON T2.column1 = T1.column1
AND T2.column2 = T1.column2
LEFT OUTER JOIN T3 ON T3.column1 = T2.column1
;
Detailed, comprehensive information with examples is available in Chapter 2 of Teradata® RDBMS SQL Reference - Volume 6 Data Manipulation Statements.
If Teradata supports NATURAL JOINs, then you're set. In MySQL, NATURAL JOINs are INNER JOINs with a USING clause. Also, you can add a LEFT|RIGHT and OUTER clauses to the NATURAL clause to further specify how you want the JOIN made.
Check the documentation of Teradata, hopefully it should support it.

What is the default MySQL JOIN behaviour, INNER or OUTER?

So I've been looking through the internet the last hour, reading and looking for the definitive answer to this simple question.
What is the default JOIN in MySQL?
SELECT * FROM t1 JOIN t2
Is that the same as
SELECT * FROM t1, t2
OR
SELECT * FROM t1 INNER JOIN t2
Also a related question, when you use "WHERE" clauses, is it the same as JOIN or INNER JOIN ?
Right now I'm thinking a stand-alone JOIN is identical to using commas and WHERE clauses.
In MySQL writing JOIN unqualified implies INNER JOIN. In other words the INNER in INNER JOIN is optional. INNER and CROSS are synonyms in MySQL. For clarity I write JOIN or INNER JOIN if I have a join condition and CROSS JOIN if I don't have a condition.
The allowed syntax for joins is described in the documentation.
Right now I'm thinking a stand-alone JOIN is nothing more than (identical to) using commas and WHERE clauses.
The effect is the same, but the history behind them is different. The comma syntax is from the ANSI-89 standard. However there are a number of problems with this syntax so in the ANSI-92 standard the JOIN keyword was introduced.
I would strongly recommend that you always use JOIN syntax rather than the comma.
T1 JOIN T2 ON ... is more readable than T1, T2 WHERE ....
It is more maintainable because the table relationships and filters are clearly defined rather than mixed together.
The JOIN syntax is easier to convert to OUTER JOIN than the comma syntax.
Mixing the comma and JOIN syntax in the same statement can give curious errors due to the precedence rules.
It is less likely to accidentally create a cartesian product when using the JOIN syntax due to a forgotten join clause, because the join clauses are written next to the joins and it is easy to see if one is missing.
These are all equivalent, and also equal to, CROSS JOIN.
There are some differences between using comma and [INNER | CROSS] JOIN syntax, which might be important when joining more tables. Pretty much all you need to know is described here in the MySQL JOIN documentation.