"Regroupement Somme (si) dans MySQL"
P粉026665919
P粉026665919 2023-09-11 13:16:22
0
1
457

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粉026665919
P粉026665919

répondre à tous(1)
P粉138871485

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.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal