この問題を単純化できると思います。私の理解が正しければ、あなたの支払いはあなたの誓約に依存します(誓約がない場合、支払いはありません)。これが true の場合、次のようなことができます。
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
トリッキーな解決策ですが、役立つかもしれません。