tags:

views:

363

answers:

3

I'm using the following statement and getting almost everything I need. In addition, I'd like to get the SUM of all of the row_total results.

    SELECT c.id AS campaign_id, c.amount AS campaign_amount, c.warning_trigger,
COUNT(cc.id) as code_count, DATEDIFF(c.end_date, CURDATE()) as days_remain,
SUM(c.amount) as row_total
FROM campaigns c
JOIN campaign_codes cc
LEFT JOIN partners p on p.id = 4
WHERE c.partner_id = 4 AND cc.status = 0 AND c.id = cc.campaign_id
GROUP BY c.id
ORDER BY campaign_amount ASC

And here's an example result, with the last column being the column I want to add together:

    1 10.00 30 992 24 9920.00
    3 25.00 30 995 290 24875.00
    16 50.00 30 988 335 49400.00
    17 100.00 30 1000 335 100000.00
+2  A: 

Encapsulate your query like:

SELECT SUM([row_total]) FROM (
Your query
) Source

From the comments below, you could try...

Your Query
UNION ALL
SELECT '', '', '', '', '', SUM([row_total]) FROM (
Your query
) Source

The union all will allow you to append an additional row to the result set which will give you a 'total row'. You can change the empty fields (the single quotes) to match your data types or assign them special values that will represent your total row.

C Bauer
Right, but that will only give me the Total and not the other info as well, correct?
k00k
You wan't keep the other information, you want the total of all the information, then there is no way to combine the rest of the rows. If you want to get the sum of every row, just add the SUM(row) over and over.Wait, do you want a separate row for the total?
C Bauer
Yes, I want to keep the other info in the result too. I would like to have a separate/additional field for the total.
k00k
+1  A: 
SELECT TB.campaign_id, TB.campaign_amount, TB.warning_trigger, TB.code_count,  TB.days_remain, TB.row_total, SUM(TB.row_total) GlobalTotal FROM (SELECT c.id AS campaign_id, c.amount AS campaign_amount, c.warning_trigger,
COUNT(cc.id) as code_count, DATEDIFF(c.end_date, CURDATE()) as days_remain,
SUM(c.amount) as row_total
FROM campaigns c
JOIN campaign_codes cc
LEFT JOIN partners p on p.id = 4
WHERE c.partner_id = 4 AND cc.status = 0 AND c.id = cc.campaign_id
GROUP BY c.id
ORDER BY campaign_amount ASC) TB
GROUP BY TB.campaign_id, TB.campaign_amount, TB.warning_trigger, TB.code_count,  TB.days_remain, TB.row_total
Tufo
@Tufo: this will only give me the total though and not all of my example results as well (which I need).
k00k
understood, youre going to do some percentage with both, hun?i've edited the code, try it now
Tufo
That throws an error of:Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
k00k
damn.... you're right, i forgot to place the group by clause, check it now
Tufo
Error is gone, but the value of the GlobalTotal is just the same as the value of the row_total.http://pastie.org/800579
k00k
+4  A: 

To get the running sum:

SELECT  c.id AS campaign_id, c.amount AS campaign_amount, c.warning_trigger,
        COUNT(cc.id) as code_count, DATEDIFF(c.end_date, CURDATE()) as days_remain,
        SUM(c.amount) as row_total, @r := @r + SUM(c.amount) AS running_sum
FROM    (
        SELECT  @r := 0
        ) vars,
        campaign c, … 

To get the grand total (and all other aggregates) as an additional record:

SELECT  *
FROM    (
        SELECT  c.id AS campaign_id, c.amount AS campaign_amount, c.warning_trigger,
                COUNT(cc.id) as code_count, DATEDIFF(c.end_date, CURDATE()) as days_remain,
                SUM(c.amount) as row_total
        FROM    campaign c, … 
        GROUP BY
                c.id WITH ROLLUP
        ) q
ORDER BY
        campaign_amount ASC

To get the total sum in an additional field:

        SELECT  c.id AS campaign_id, c.amount AS campaign_amount, c.warning_trigger,
                COUNT(cc.id) as code_count, DATEDIFF(c.end_date, CURDATE()) as days_remain,
                SUM(c.amount) as row_total,
                (
                SELECT  SUM(c.amount)
                FROM    campaign c, …
                -- the same but without the GROUP BY and ORDER BY clauses. 
                )
        FROM    campaign c, …
        GROUP BY
                c.id
        ORDER BY
                campaign_amount ASC
Quassnoi
+1, that's some useful tricks you've got there!
Jørn Schou-Rode
Quassnoi: this is pretty slick. And it works well if I leave off the ORDER BY, otherwise the ORDER BY throws an error of: Incorrect usage of CUBE/ROLLUP and ORDER BY
k00k
@k00k: sure, forgot about that. Just wrap it into a nested query. I'll update the post.
Quassnoi
@Quassnoi: thanks, works well. Though now I'm thinking it would be better if the ROLLUP wasn't an additional record but instead if it was an additional field. This will help on my view layer so I don't display the values in a foreach() loop. Possible?
k00k
After reading a bit more about ROLLUP, I don't think it is possible to put the ROLLUP values in a new field. For now I'm going to use this solution, although the ORDER BY is troublesome as it is hard to really massage it the way I want. For now I'm checking for a NULL value on the view layer.
k00k
@Quassnoi: your last example works perfectly, thanks! Chosen!
k00k