只是为了提供一个快速的 DDL 让我的问题更容易理解:
------------------ 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);
现在我基本上将使用这种方式获取经理的姓名:
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;
我感兴趣的部分是:
left join managers m
join users mu on mu.user_id = m.user_id
on m.manager_id = t.manager_id
这对 PostgreSQL 来说是什么?一个后缀?就像它如何解释这个以及做这样的事情和这个有什么区别:
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
编辑:
经过大量测试,结果证明这两种方法绝对、100%、1:1 相同。相同的执行计划,相同的执行时间(具有微小的毫秒变化),使用第一种方法获得的唯一好处就是代码更简洁,并且在具有大量子查询连接的更大函数中更容易遵循。
文档告诉你:
解析表达式的唯一方法
符合上述语法的是
因此,如果您的代码没有引发语法错误,那就必须这样解释它。