Home > Software engineering >  Sql code returns unexpected results. How to correct it
Sql code returns unexpected results. How to correct it

Time:11-20

I'm using Firebird 3. There are 'sellers' master table for my contragent sellers, detailed 'Doc' table for goods income documents and subdetail table 'paym' for payments.

Seller: Seller_id, seller
Docs: doc_id, doc_summa, part_id
Paym: paid_id, doc_id, paid

Seller:

seller_id seller
8 Firm1
45 Firm2

Docs:

doc_id doc_summa seller_id
346 1000 8
347 600 45
348 800 45

Paym:

paym_id doc_id paid
1 346 100
2 346 100
3 347 200
4 348 100
5 348 50

My aim is to get my residual debts(income-payment) like this:

seller_id summa paid debt
8 1000 200 800
45 1400 350 1050

but get this multiplied, wrong summas:

seller_id summa paid debt
8 2000 200 800
45 2200 350 1850
SELECT
 s.seller_id, 
 sum(d.doc_summa) as summa,
 sum(p.paid) as paid,
 sum(d.doc_summa)-sum(p.paid) as debt

FROM seller s Left Join Docs d  on s.seller_id=d.seller_id
             Left Join  paym p  on p.doc_id= d.doc_id

GROUP BY s.seller_id

What is wrong in my SQL code?

CodePudding user response:

The problem with your query is that because there are multiple payments for doc_ids 346 and 348, you will have two rows with a doc_summa of 1000 and 800 respectively, when you then sum them, the total becomes 2000 for seller_id 8 and 2200 for seller_id 45.

To solve this, you need to consolidate (sum) the payments before joining with docs. For example like the following:

with consolidated_paym as (
  select 
    doc_id, 
    sum(paid) as total_paid
  from paym
  group by doc_id
)
select
  s.seller_id,
  sum(d.doc_summa) as summa,
  sum(p.total_paid) as paid,
  sum(d.doc_summa - p.total_paid) as debt
from seller s
left join docs d
  on d.seller_id = s.seller_id
left join consolidated_paym as p
  on p.doc_id = d.doc_id
group by s.seller_id

Fiddle: https://dbfiddle.uk/6_vyCu0w

  • Related