我正在尝试编写一个连接多个一对多表的SELECT
查询。名为支出的表格同时包含LEFT JOIN
到名为联系人的表格(因为联系人可以有多笔付款)和LEFT JOIN
到表格名为承诺(因为承诺(付款承诺)可以有多笔付款(实际付款)。
我的问题是我如何提取列出联系人的记录,他们的承诺和质押余额(从质押中减去承诺的支出总额)?
这是我到目前为止所得到的:
SELECT *, (p.pl_amount - SUM(disb_amount)) as balance FROM disbursements d
LEFT JOIN contacts c on c.c_no = d.c_no
LEFT JOIN pledges p on d.pl_no = p.pl_no
GROUP BY d.disb_no
HAVING balance > 500
ORDER BY c.c_last
提前谢谢
答案 0 :(得分:0)
您可能想要做的是将contacts
表放在FROM
子句而不是LEFT JOIN
中,因为您仍然希望检索联系人,即使他们不是有任何支出/承诺。
此外,因为您似乎只想要具有承诺余额的联系人> 500
,除非您还想要检索没有任何承诺或有余额>的联系人,否则不需要LEFT JOIN
。 500
。我使用常规(内部)JOIN
代替:
试试这个:
SELECT c.*,
p.*,
COALESCE(p.pl_amount - pd.disb_sum, 0) AS pledge_balance
FROM contacts c
LEFT JOIN disbursements d ON c.c_no = d.c_no
LEFT JOIN pledges p ON d.pl_no = p.pl_no
LEFT JOIN (
SELECT pl_no, SUM(disb_amount) AS disb_sum
FROM disbursements
GROUP BY pl_no
) pd ON p.pl_no = pd.pl_no
WHERE p.pl_no IS NULL OR
p.pl_amount - pd.disb_sum > 500
ORDER BY c.c_last
答案 1 :(得分:0)
我认为你可以简化这个问题。如果我理解正确,您的支出取决于您的承诺(如果没有承诺,则没有支付)。如果这是真的,那么你可以这样做:
select
p.pl_no, p.pl_amount - sum(disb_amount) as balance
from
pledges as p
left join disbursements as d on p.pl_no = d.pl_no
group by
p.pl_no
having
p.pl_amount - sum(disb_amount) > 500;
如果您需要完整信息(联系人,承诺和支出),那么您必须将此视为一个多步骤问题:
因此,上面的查询为您提供了步骤1所需的信息。您可以使用以下信息创建临时表:
Create temporary table temp_pledge_balance
select
p.pl_no, p.pl_amount - sum(disb_amount) as balance
from
pledges as p
left join disbursements as d on p.pl_no = d.pl_no
group by
p.pl_no;
我建议您将此表编入索引,以加快后续步骤:
Alter table temp_pledge_balance
add index pl_no (pl_no);
现在,对于第2步:
create temporary table temp_contacts
select c.*, p.pl_no
from
temp_pledge_balance as pb
inner join pledges as p on pb.pl_no=p.pl_no
inner join contacts as c on p.c_no = c.c_no;
alter temp_contacts
add index c_no(c_no);
最后,对于第3步:
select
tc.*, pb.*, p.*, d.*
from
temp_contacts as tc
left join disbursements as d on tc.c_no = d.c_no
left join pledges as p on d.pl_no = p.pl_no
left join temp_pledge_balance as pb on p.pl_no = pb.p_no
where
pb.balance > 500
一个棘手的解决方案,但它可能对你有帮助。