Apenas para dar um DDL rápido para tornar minha pergunta mais fácil de entender:
------------------ creating tables ------------------
create table if not exists users(
user_id bigserial primary key,
first_name text,
last_name text,
user_name text
);
create table if not exists managers(
manager_id bigserial primary key,
user_id bigint references users(user_id) not null,
permissions text[]
);
create table if not exists transactions(
transaction_id bigserial primary key,
user_id bigint references users(user_id) not null,
amount numeric,
is_approved boolean,
manager_id bigint references managers(manager_id) null
);
------------------ inserting data ------------------
insert into users(first_name, last_name, user_name)
values ('first_name','last_name','ohyea'),
('manager','manager','manager');
insert into managers(user_id)
values (2);
insert into transactions(user_id, amount, is_approved, manager_id)
values (1,10,true,null),
(1,1000,true,1);
Agora, basicamente, obterei o nome do gerente usando desta maneira:
select
t.transaction_id,
t.user_id,
u.user_name,
t.amount,
t.is_approved,
mu.user_name as manager_name
from transactions t
join users u on u.user_id = t.user_id
left join managers m
join users mu on mu.user_id = m.user_id
on m.manager_id = t.manager_id;
A parte que me interessa é esta:
left join managers m
join users mu on mu.user_id = m.user_id
on m.manager_id = t.manager_id
O que é isso para o PostgreSQL? Uma suqueria? Tipo, como ele interpreta isso e qual é a diferença entre fazer algo assim e isso:
left join (
select m.manager_id, u.user_name
from managers m
join users u on u.user_id = m.user_id
) mu on mu.manager_id = t.manager_id
EDITAR:
Depois de muitos testes, ambas as abordagens são absolutamente, 100%, 1:1 idênticas. Mesmo plano de execução, mesmos tempos de execução (com pequenas variações de milissegundos), o único benefício que você ganha usando a primeira abordagem é apenas um código mais limpo e mais fácil de seguir em funções maiores com muitas junções de subconsulta.
A documentação informa:
A única maneira de analisar a expressão
que está de acordo com a sintaxe acima é
então se o seu código não lançar um erro de sintaxe, é assim que ele deve ser interpretado.