2016-12-13 1 views
0

Collé à ce sujet un peu aujourd'hui et je me demandais si quelqu'un pouvait suggérer ce qui ne va pas. Voici mon code:ROLLUP retournant une valeur incorrecte

select g.game_name, r.rental_id, sum(if(datediff(r.return_date, r.due_date) > 0, datediff(r.return_date, r.due_date) * g.overdue_charge_per_day, 0)) Overdue_Charges 
from rental as r 
left join game as g 
on r.game_id = g.game_id 
where month(r.return_date)=month(now()) 
group by rental_id 
with rollup; 

Cette affiche les éléments suivants:

GTA V 12 4,00

Tony Hawk 13 15.00

Tony Hawk null 19.00

Il totalise 4 & 15. Cependant, je ne veux pas qu'il affiche deux fois "Tony Hawk". Puis-je le remplacer par Grand Total? Peut-être que c'est un problème d'adhésion et le deuxième Tony Hawk devrait aussi être nul. Merci

Répondre

1

Ce comportement est expliqué dans la section "GROUP BY Modifiers" de la documentation:

MySQL autorise une colonne qui ne figure pas dans la liste GROUP BY être nommés dans la liste de sélection. Dans ce cas, le serveur est libre de choisir n'importe quelle valeur de cette colonne non agrégée dans les lignes récapitulatives, et cela inclut les lignes supplémentaires ajoutées par WITH ROLLUP. Par exemple, dans la requête suivante, le pays est une colonne non agrégée qui ne figure pas dans la liste GROUP BY et les valeurs choisies pour cette colonne sont indéterminée:

mysql> SELECT year, country, SUM(profit) 
    -> FROM sales GROUP BY year WITH ROLLUP; 
+------+---------+-------------+ 
| year | country | SUM(profit) | 
+------+---------+-------------+ 
| 2000 | India |  4525 | 
| 2001 | USA  |  3010 | 
| NULL | USA  |  7535 | 
+------+---------+-------------+ 

Ce problème se produit si le mode ONLY_FULL_GROUP_BY SQL n'est pas activé. Si ce mode est activé, le serveur rejette la requête comme illégale car le pays n'est pas répertorié dans la clause GROUP BY.

Maintenant, pour montrer une autre valeur « Grand total », vous pouvez utiliser une requête d'emballage avec un if comme celui-ci:

select if(rental_id is null, 'Grand Total', game_name) game_name, 
      rental_id, 
      Overdue_Charges 
from  ( 
     select game_name 
        r.rental_id, 
        sum(if(datediff(r.return_date, r.due_date) > 0, 
         datediff(r.return_date, r.due_date) * g.overdue_charge_per_day, 
         0)) Overdue_Charges 
     from  rental as r 
     left join game as g 
       on r.game_id = g.game_id 
     where  month(r.return_date)=month(now()) 
     group by rental_id 
     with rollup) sub; 
+0

Hey, mais affiche toujours le nom Tony Hawk deux fois, est-il un problème avec ma jointure? –

+0

La jointure est OK. Vous devrez peut-être le mettre dans une sous-requête et faire le 'if 'supplémentaire dans la requête externe. – trincot