2010-01-29 17 views
8

J'utilise l'instruction suivante et j'obtiens presque tout ce dont j'ai besoin. En outre, j'aimerais obtenir la somme de tous les résultats row_total.MySQL - Comment obtenir SUM d'un COUNT d'un champ?

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 

Et voici un résultat d'exemple, la dernière colonne étant la colonne que je veux additionner:

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 
+0

Voulez-vous à la fois les données curr affiché dans votre exemple * et * la somme des valeurs de la dernière colonne? Si oui: ne pouvez-vous pas additionner les valeurs dans la couche application? –

+0

Oui, je veux à la fois les données que j'ai affichées ET la somme des valeurs de la dernière col. Je pourrais l'ajouter ensemble dans le contrôleur ou voir le calque, mais je le pensais le mieux adapté au modèle. – k00k

Répondre

11

Pour obtenir la somme en cours d'exécution:

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, … 

Pour obtenir le grand total (et tous les autres agrégats) comme un enregistrement supplémentaire:

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 

Pour obtenir la somme totale dans un champ supplémentaire:

 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 
+0

+1, c'est quelques trucs utiles que vous avez ici! –

+0

Quassnoi: c'est assez joli. Et cela fonctionne bien si je laisse la commande ORDER BY, sinon l'ordre BY jette une erreur de: Utilisation incorrecte de CUBE/ROLLUP et ORDER BY – k00k

+0

@ k00k: bien sûr, oublié à ce sujet. Juste envelopper dans une requête imbriquée. Je vais mettre à jour le post. – Quassnoi

4

encapsulent votre requête comme:

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

D'après les commentaires ci-dessous, vous pourriez essayer ...

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

L'union vous permettra d'ajouter une ligne supplémentaire au jeu de résultats qui vous donnera une 'ligne totale'. Vous pouvez modifier les champs vides (les guillemets simples) pour qu'ils correspondent à vos types de données ou leur attribuer des valeurs spéciales qui représenteront votre ligne totale.

+0

Oui, mais cela ne me donnera que le total et pas les autres infos, n'est-ce pas? – k00k

+0

Vous ne gardez pas les autres informations, vous voulez le total de toutes les informations, alors il n'y a aucun moyen de combiner le reste des lignes. Si vous voulez obtenir la somme de chaque ligne, ajoutez simplement la somme (rangée) encore et encore. Attendez, voulez-vous une ligne séparée pour le total? –

+0

Oui, je veux garder les autres infos dans le résultat aussi. Je voudrais avoir un champ séparé/supplémentaire pour le total. – k00k

1
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 
+0

@Tufo: cela ne me donnera que le total et pas tous mes exemples de résultats (dont j'ai besoin). – k00k

+0

compris, vous allez faire un certain pourcentage avec les deux, hun? J'ai édité le code, essayez-le maintenant – Tufo

+0

Cela génère une erreur de: Le mélange de colonnes GROUP (MIN(), MAX(), COUNT(), ...) sans colonnes GROUP est illégal s'il y a pas de clause GROUP BY – k00k