There is a logical order to follow.
For your model, you can change the order of your joins without any problem. This is because all of them are based on a main table that will always be present to perform their comparisons (Person table).
But that may not always be the case.
Imagine a system with the following tables:
tb_pessoa tb_pessoa_juridica tb_pessoa_usuario
------------------ ------------------ ------------------------
id_pessoa id_pessoa id_pessoa
dc_apelido dc_razao_social dc_usuario_login
dc_email dc_cnpj dc_senha
Not all people have access to the system, that is, not all have a record in tb_pessoa_usuario
. Also not all are legal entities, only those that are registered in tb_pessoa_juridica
.
Imagine a scenario in a listing where your customer wants to know who all the people with access to the system are (ie, those with a user registration). Also, all legal entities should appear, and the user will be listed if there are any. If the legal entity does not have a user, it wants them to appear in the listing so that it can register a user for them.
See the case of a SELECT
where the order imports:
SELECT
p.id_pessoa
,p.dc_apelido
,p.dc_email
,u.dc_usuario_login
,j.dc_razao_social
FROM
tb_pessoa p -- (1)traz todas as pessoas
LEFT JOIN
tb_pessoa_juridica j ON -- (2)junta informações da jurídica se houver
p.id_pessoa = j.id_pessoa
INNER JOIN -- (3)erro: agora pega somente as que tem usuário
tb_pessoa_usuario u ON
p.id_pessoa = u.id_pessoa
The INNER JOIN
in point (3) is destroying its LEFT JOIN
in point (2). This is because you do not want all the information in the start table, you want a INNER
association between tb_pessoa
and tb_pessoa_usuario
. So you can not make a LEFT JOIN
, you will get people who are not users.
The correction would be to change the order from (2) to (3):
SELECT
p.id_pessoa
,p.dc_apelido
,p.dc_email
,u.dc_usuario_login
,j.dc_razao_social
FROM
tb_pessoa p -- (1)traz todas as pessoas
INNER JOIN -- (2)pega somente as que tem usuário
tb_pessoa_usuario u ON
p.id_pessoa = u.id_pessoa
LEFT JOIN
tb_pessoa_juridica j ON -- (3)junta informações da jurídica se houver
p.id_pessoa = j.id_pessoa
In this case, we are first taking information that is mandatory and then joining with information that may appear.
There is no rule to follow, only logic. But I like to take some precautionary measures in my constructions:
Always first use% s of% s when there is. If there are INNER JOIN
s, place them later
OUTER JOIN
are calculated faster than INNER JOINS
s, so your query gets faster when they start first.
Try to associate your% s of% s (all of them, OUTER JOIN
and JOIN
) with primary keys (PK) of one table with the foreign keys (FK) of the others. Do not put a filter on INNER
, use filters on OUTER
. Information is linked faster with keys. Do not mix association (keys) with filters !!!!!!!!!!!!!!!!!
Study ON
if you are using Microsoft SQL Server databases! It can be much better than% s of% s in many situations! This has a lot to do with the order in which the database selects the data and then filters the data.