2017-08-31 98 views
0

我有以下查询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 '2017-08-01 00:00:00' AND '2017-08-31 23:59:59' 
GROUP BY a.account_id 
ORDER BY account_id ASC; 

我希望所有从accounts a行和零丢失的数据量是。为不同类型的连接和不同的连接结构设置相同的结果集 - 只有在p中有一些付款的行。

我该在哪里出错?

回答

1

简体:

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子句实际上是您的解决方案中的真正问题,因为它会过滤掉您希望在endresult中存在的行。最重要的是:你遗漏了其他表的左连接。我创建了一个简化的测试数据库:

$ 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); 
+0

这个查询确实有效,但是只要我应用WHERE子句,它就会在给定期间内返回几条记录在'payments'中的行。在发布问题之前,我已经尝试过'COALESCE' – mariobgr

+0

答案已被编辑。 –

+0

现在我们在说':) Mucho谢谢,像魅力一样工作! – mariobgr