Abcdfpq Vpn
Abcdfpq Vpn

Reputation: 13

Comparing the value of a field in one table to the sum of multiple fields in another table

I have two tables

Whenever a 'package' is obtained, an entry is made in the 'transactions' table, together with the quantity obtained. multiple 'transactions' can be performed and when the package is fully obtained, the sum of all transactions for that package should be equal to the quantity for that package in the packages table.

I want to write a SQL statement to check if a particular packageid has NOT been fully obtained, ie:

  1. no transactions were performed
  2. transactions were performed but the sum of the quantities of all transactions is less than the quantity in the package table

how can I achieve this? every join i try to use is only catering for number 2 but does not factor in packages that have had no transactions

i tried:

select package.packageid, package.quantity, sum(transactions.quantity) from package join transactions on package.packageid = transactions.packageid where package.quantity > sum(transactions.quantity)

also tried left join but it does not work. ideally i want all packages listed from the left table in the result with null values on the right where necessary

Upvotes: 1

Views: 1960

Answers (1)

Tim Pote
Tim Pote

Reputation: 28049

If you want to include the packages which have no transactions, then you need to left outer join. This will keep all of the packages in the results and match transactions where transactions exists.

Then you need to group by package.packageid so that your sum operation only works on transactions records that belong to a certain packageid.

Then you use a having clause, which is similar to a where clause, only it works with aggregate functions like sum.

select
  p.packageid,
  p.quantity,
  sum(t.quantity) as transaction_sum
from
  packages p
  left outer join transactions t on (t.packageid = p.packageid)
group by
  p.packageid,
  p.quantity
having
  coalesce(sum(t.quantity), 0) != p.quantity
;

The coalesce just says, "take the first non-null value." So if sum(t.quantity) returns null then it will use 0 instead. This will make sure that packages with a quantity, but no transactions are included in the result set.

I would advise that you read up on group by and having. They are indispensable when working with sql. In essence, group by splits your data into groups based on criteria they have in common. Then having filters out certain results based on qualities of the group.

Upvotes: 1

Related Questions