Home > Back-end >  How to join a sum()'s result with a select query
How to join a sum()'s result with a select query

Time:11-18

I've got a basic transactions table with 4 total columns as follows :

`transaction_id` int(11) NOT NULL AUTO_INCREMENT,
`fruit_id` int(11),
`person_id` int(11),
`quantity_bought` int(11),

example select * query :

transaction_id fruit_id person_id quantity_bought
1 banana alex 65
2 banana joe 25
3 banana jenny 70
4 apple dan 80
4 apple danny 50

i'm required to add the total_quantity_bought of each fruit to every row of this select query :

SELECT transactions.* FROM transactions;

here's an example of the desired output :

transaction_id fruit_id person_id quantity_bought total_quantity_bought
1 banana alex 65 160
2 banana joe 25 160
3 banana jenny 70 160
4 apple dan 80 130
4 apple danny 50 130

this is what i tried so far and miserably failed :

select x.* , y.total_quantity_bought
from
   (SELECT *
    FROM transactions) x
    cross join
   (SELECT fruit_id , SUM(quantity_bought) AS total_quantity_bought
    FROM transactions
    GROUP BY fruit_id) y

i thought of creating a View for sums like so, but i'm looking for a solution that doesnt require a View

fruit_id total_quantity_bought
banana 160
apple 130

any help appreciated.

CodePudding user response:

You are basically there. Your JOIN wants to specify that for everything on the left (from the transactions table) should join to one associated total from the right (the totals subquery) ... and that join should be conditional on a matching fruit_id.

The performance of this query may drag (severely) as the dataset grows. You might want to look at either caching the totals (using a database trigger etc) or rendering the totals in code elsewhere.

If you go for the latter (rendering it elsewhere), you might be interested in the WITH ROLLUP function:

https://mariadb.com/kb/en/select-with-rollup/

SELECT
   transactions.*,
   totals.total_quantity_bought
FROM
   transactions   -- These are the individual transactions

   INNER JOIN     -- Join each individual transaction against the calculated totals

   (
    SELECT
       fruit_id,
       SUM(quantity_bought) AS total_quantity_bought
    FROM transactions
    GROUP BY fruit_id
   ) as totals    -- These are the calculated totals (subqueried)

   ON totals.fruit_id = transactions.fruit_id
                  -- This joins the individual records to the totals by `fruit_id`

(Demo: http://sqlfiddle.com/#!9/74ae7e/10 )

CodePudding user response:

Possibly I just got beat to the answer, but here's my attempt

SELECT t.transaction_id, t.fruit_id, t.person_id, t.quantity_bought, grouped_fruit.total_quantity_bought
FROM transactions t
JOIN (
    SELECT fruit_id, SUM(quantity_bought) total_quantity_bought
    FROM transactions
    GROUP BY fruit_id
) grouped_fruit ON t.fruit_id = grouped_fruit.fruit_id
  • Related