Sample SQL Join Code from Famous Sites Doesn't Validate? - sql

Here's sample SQL Full Outer Join code from w3schools:
SELECT column_name
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;
Testing it in online validators (https://www.piliapp.com/mysql-syntax-check/ and https://www.eversql.com/sql-syntax-check-validator/) throws an error:
You have an error in your SQL syntax; it seems the error is around: 'OUTER JOIN table2 ON table1.column_name = table2.column_name' at line 5
w3resource has this sample SQL code:
SELECT *
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;
Sample code found on SO is pretty much the same code and throws the same error in the validators and on my dev system.
Does that make any sense?
What is the correct SQL for this?

Those query are MSSQL Query not mysql and that two sites are mysql query validator.
You don't have FULL JOINS on MySQL, but you can sure emulate them.
sample code to emulate FULL OUTER JOIN on MYSQL :
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION ALL
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
WHERE t1.id IS NULL

Related

Getting a syntax error for trying to get values from two different databases

select *
from DB1.schemaA.table1 as t1
outer join DB2.schemaA.table1 as t2
on t1.ID = t2.ID
error being - Incorrect syntax near the keyword 'join'
The outer join query syntax is not correct, please use full outer join
Since you didn't mention which SQL database being used, so here is a general guide: W3School SQL FULL OUTER JOIN Keyword
Try writing:
select * from DB1.schemaA.table1 as t1 full outer join DB2.schemaA.table1 as t2 on t1.ID = t2.ID;

When to use right join or full outer join

I work with DB / SQL almost on a daily basis and the more I work with sql, the more I'm the opinion that there is no reason to use a right join or a full outer join.
Let's assume we have two tables: table1 and table2. Either I want to receive additional information for the rows in table1 so I can use an inner join on table2 and if I want to keep the original rows if there is no match, I use the left join then:
In case I have to add additional information to table 2, I can do the same and left join table 2 to table on. So I do not see a reason why I should ever use a right join. Is there any use case where you can not use a left join for a right join?
I also wondered if I would ever need a full outer join. Why would you join two tables and keep the rows that do not match of BOTH tables? We you could also achieve this by using two left joins.
Why would you join two tables and keep the rows that do not match of BOTH tables?
The full join has cases where it is useful.One of them is comparing two tables for differences like XOR between tables:
SELECT *
FROM t1
FULL JOIN t2
ON t1.id = t2.id
WHERE t1.id IS NULL
OR t2.id IS NULL;
Example:
t1.id ... t2.id
1 NULL
NULL 2
you could also achieve this by using two left joins.
Yes you could:
SELECT t1.*, t2.*
FROM t1
LEFT JOIN t2
ON t1.id = t2.id
WHERE t2.id IS NULL
UNION ALL
SELECT t1.*, t2.*
FROM t2
LEFT JOIN t1
ON t1.id = t2.id
WHERE t1.id IS NULL;
Some SQL dialects does not support FULL OUTER JOIN and we emulate it that way.
Related: How to do a FULL OUTER JOIN in MySQL?
On the other hand RIGHT JOIN is useful when you have to join more than 2 tables:
SELECT *
FROM t1
JOIN t2
...
RIGHT JOIN t3
...
Of course you could argue that you could rewrite it to correspodning form either by changing join order or using subqueries(inline views). From developer perspective it is always good to have tools(even if you don't have to use them)

Joining Table via Linked Server

I have 2 servers with 2 different databases.
S1(Server) WITH DB1(Database) WITH T1(Table)
and
S2(Server) WITH DB2(Database) WITH T2(Table)
DB1 has a linked server to S2 DB2.
So i can run a query such as
SELECT * FROM T1
JOIN [S2].[DB2].[T2] T2
ON T1.[ID] = T2.[ID]
And this runs correctly.
However, how can i run it in the opposite direction
e.g.
SELECT * FROM T2
JOIN [S1].[DB1].[T1] T1
ON T2.[ID] = T1.[ID]
This errors with "Could not find server [S1].[DB1].[T1]"
Is there anyway i can join in this direction without having to create a linked server from S2 to S1?
This query:
SELECT *
FROM T2 JOIN
[S1].[DB1].[T1] T1
ON T2.[ID] = T1.[ID];
Presumes that T2 is local. You can sort of do a hybrid:
SELECT *
FROM [S2].[DB2].[T2] T2 JOIN
[DB1].[T1] T1
ON T2.[ID] = T1.[ID];
It is possible to link a server to itself, so if you did that, you could run this identical query on both servers:
SELECT *
FROM [S2].[DB2].[T2] T2 JOIN
[S2].[DB1].[T1] T1
ON T2.[ID] = T1.[ID];
If you are trying to implement "equivalent" queries on two servers, then synonyms could help. You might be interested in the answers to this question.
Gordon's answer is more thorough but you can rewrite your second query as:
SELECT *
FROM [S2].[DB2].[T2] T2
JOIN T1
ON T2.ID = T1.ID

Exactly when to user inner join or an alternative query

SELECT .... FROM TABLE1 T1, TABLE2 T2, TABLE3 T3
WHERE T1.NAME = 'ABC' AND T1.ID = T2.COL_ID AND T2.COL1 = T3.COL2
vs
SELECT .... FROM TABLE1 T1
WHERE T1.NAME = 'ABC'
INNER JOIN TABLE2 T2 ON T1.ID = T2.COL_ID
INNER JOIN TABLE3 T3 ON T2.COL1 = T3.COL2
Two questions
In terms of performance, which will perform better and why?
If Option 2 has the better performance, when should be using Option 1? (vice versa question if Option 1 has better performance)
The second query is not correct. It should be:
SELECT .... FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T1.ID = T2.COL_ID
INNER JOIN TABLE3 T3 ON T2.COL1 = T3.COL2
WHERE T1.NAME = 'ABC'
This is the right way to write your join condition. The 1st one is accepted, but technically creates a cartesian product. All modern database deals perfectly with both 1st and 2nd queries and interprets them the same way, therefore, performance should be the same. But still, you should use the second one because it is more readable and allows you to have only one way to write join weither it is a inner, left or full outer.
The answer is easy: Don't use comma-separated joins (first query). We used these in the 1980s for the lack of something better, but then in 1992 the new syntax (second query) was introduced1, because the old syntax was error-prone (it was easier to forget to apply join criteria) and harder to maintain (was missing join criteria intended or not in a query?) and there was no standard syntax for outer joins.
1 Oracle was a little late though featuring the new syntax. They introduced the new ANSI joins in Oracle 9i in 2001.
In terms of performance: There should be no difference in speed, because DBMS optimizers see that this is essentially the same query.
Your second query is syntactically incorrect by the way. The query's WHERE clause belongs after the complete FROM clause, i.e. after all the joins:
SELECT ....
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.col_id
INNER JOIN table3 t3 ON t2.col1 = t3.col2
WHERE t1.name = 'ABC';

SQL issue: JOIN on empty table

For example we have the following SQL query
select T1.name
from table1 T1
join table2 T2 ON T1.id = T2.id
I have made join table2 only if it is NOT empty. If table2 is empty I don't make join
select T1.name
from table1 T1
Can I solve it by one SQL query?
It would be good to use only SQL standard.