Postgresql 多个表的左连接问题

Postgresql 多个表的左连接问题,postgresql,join,left-join,Postgresql,Join,Left Join,我有以下疑问 SELECT a.account_id, sum(p.amount) AS amount FROM accounts a LEFT JOIN users_accounts ua JOIN users u JOIN payments p on p.meta_id = u.user_id ON u.user_id = ua.user_id ON ua.account_id = a.account_id WHERE p.date_prcsd BETWEEN

我有以下疑问

SELECT a.account_id, sum(p.amount) AS amount
FROM accounts a
LEFT JOIN users_accounts ua
    JOIN users u
        JOIN payments p on p.meta_id = u.user_id
    ON u.user_id = ua.user_id
ON ua.account_id = a.account_id
WHERE p.date_prcsd BETWEEN '2017-08-01 00:00:00' AND '2017-08-31 23:59:59'
GROUP BY a.account_id
ORDER BY account_id ASC;
我想要的是
帐户a中的所有行以及缺失金额数据的零。对于不同类型的联接和不同的联接结构,相同的结果集-仅限在p中具有某些付款的行

哪里出错?

简化:

SELECT a.account_id
,sum(coalesce(p2.amount, 0)) AS amount
FROM accounts a
LEFT JOIN users_accounts ua ON (a.account_id = ua.account_id)
LEFT JOIN users u ON (ua.user_id = u.user_id)
LEFT JOIN (
    SELECT p.meta_id
    ,p.amount
    FROM payments p
    WHERE p.date BETWEEN '2017-08-01' AND '2017-08-10'
) AS p2 ON (u.user_id = p2.meta_id)
GROUP BY a.account_id
ORDER BY account_id ASC;
结果:

  account_id | amount
 ------------+--------
           1 |      4
           2 |      0
           3 |      0
 (3 rows)
说明:您需要处理所有返回的空值。coalesce()为您实现了这一点。where子句实际上是解决方案中的真正问题,因为它过滤掉了您希望在最终结果中包含的行。最重要的是:您遗漏了其他表的左连接。我创建了一个简化的测试数据库:

$ cat tables.sql
drop table users_accounts;
drop table payments;
drop table users;
drop table accounts;

create table accounts (account_id serial primary key, name varchar not 
null);
create table users (user_id serial primary key, name varchar not null);
create table users_accounts(user_id int references users(user_id),
                            account_id int references 
                            accounts(account_id));
create table payments(meta_id int references users(user_id), amount int 
not null, date date);

insert into accounts (account_id, name) values (1, 'Account A'), (2, 
'Account B'), (3, 'Account C');
insert into users (user_id, name) values (1, 'Marc'), (2, 'Ruben'), (3, 
'Isaak');
insert into users_accounts (user_id, account_id) values (1,1),(2,1);
insert into payments(meta_id, amount, date) values (1,1, '2017-08-01'),
(1,2, '2017-08-11'),(1,3, '2017-08-03'),(2,1, null),(2,2, null),(2,3, 
null);

这个查询确实有效,但只要我应用
WHERE
子句,它就会返回在给定期间
payments
中有记录的几行。在发布问题之前,我已经尝试了
COALESCE
,但没有成功。现在我们正在讨论:)谢谢,效果很好!