Maison  >  Questions et réponses  >  le corps du texte

"Regroupement Somme (si) dans MySQL"

J'ai le tableau suivant qui ne se charge pas : date de paiement, ID de l'utilisateur, MonthlyAmount_last30d

L'ID utilisateur et la date de paiement proviennent du tableau. Dans monthlyAmount_last30d字段 je souhaite voir le montant pour la période (date de paiement - 30 jours).

Je n'arrive pas à comprendre comment regrouper correctement ces colonnes pour obtenir un résultat comme celui-ci. Si je regroupe uniquement par user_id, je ne vois qu'une première ligne avec la date de paiement (j'ai besoin de toutes les lignes, chacune avec le total de paiement pour cet identifiant utilisateur qui est la date de paiement pour cette ligne - la somme de 30 jours). Si je regroupe par les deux champs -> le montant du paiement que je reçois est toujours égal au montant du paiement pour cette ligne et non au montant réel pour la période dont j'ai besoin.

select
order_id,
order_date,
sum( if( ( order_date <= order_date 
         and order_date >= order_date - interval 30 day), order_cost_rub, 0)) monthlyAmount_last30d,
用户身份,
order_cost_rub

from MyTable

group by
user_id

Merci pour vos conseils !

Mise à jour :

Exemple de données :

identifiant_utilisateur Date de paiement order_cost_rub
1 2022-01-01 12:00:00 100
1 2022-01-01 13:00:00 100
1 2022-01-03 20:00:00 150
2 2022-01-03 16:00:00 200
2 2022-01-15 11:00:00 300

Résultats attendus :

identifiant_utilisateur Date de paiement order_cost_rub monthlyAmount_last30d
1 2022-01-01 12:00:00 100 100
1 2022-01-01 13:00:00 100 200
1 2022-01-03 20:00:00 150 350
2 2022-01-03 16:00:00 200 200
2 2022-01-15 11:00:00 300 500

P粉026665919P粉026665919380 Il y a quelques jours387

répondre à tous(1)je répondrai

  • P粉138871485

    P粉1388714852023-09-12 10:16:40

    Je pense que ce que vous essayez dans IF() est faux. Je pense que ce que vous demandez devrait être appliqué dans une clause WHERE comme

    Je veux tous les enregistrements de transactions de toutes les personnes ayant eu lieu au cours des 30 derniers jours. A partir de là, je veux le total de tous leurs achats, regroupés par chaque personne. Cela vous semble correct ?

    select
          user_id,
          payment_date,
          order_cost_rub,
          sum( order_cost_rub ) 
             OVER ( PARTITION BY user_id 
                    order by payment_date ) AS monthlyAmount_last30d
       from 
          MyTable
       where
          order_date >= subdate(curdate(), interval 30 day)

    En appliquant la clause WHERE de la requête, vous n'obtenez jamais d'enregistrements de transaction précédents, il n'est donc pas nécessaire d'appliquer des vérifications conditionnelles IF() sur chaque enregistrement.

    Requête révisée. Vous souhaitez donc afficher tous les enregistrements, mais uniquement sur 30 jours en arrière. Ainsi, la clause WHERE s'applique toujours. Mais maintenant, j'affiche toutes les colonnes de tous les enregistrements normaux. Jetez un œil à SUM(). Cela fait le total cumulé que vous avez demandé.

    Notez la clause OVER après (je l'ai mise en retrait juste pour montrer son contexte par rapport à la procédure sum()). OVER spécifie le partitionnement (similaire au group by, mais pas à un group by externe ordinaire). Cela signifie simplement redémarrer lorsque cette valeur de partition change. Dans ce cas, il s'agit de l'ID utilisateur. Et les données sont triées dans l'ordre payment_date via l'instruction ORDER BY dans la partition.

    Je pense que cela devrait répondre à vos besoins.

    répondre
    0
  • Annulerrépondre