0
votes

MySQL - Opérations arithmétiques avec deux relations

Comment puis-je obtenir le montant total de l'argent payé par chaque client moins le montant collecté ( em_paid_to code>)?

Client de table P>

SELECT C.F_NAME, C.L_NAME, COUNT(T.EM_PAID_TO), SUM(T.AMOUNT)
FROM CUSTOMER C 
JOIN TRANSACTION T ON C.EMAIL = T.EM_PAID_TO;


4 commentaires

De quelle manière vos requêtes ne fonctionnaient pas? Résultat incorrect? Message d'erreur? Aidez nous à vous aider...


Vous devez tester si t_amount devrait être annulé dans la somme. (Étui à indice) et recherchez une agrégation conditionnelle.


C'est l'erreur que je reçois. ERREUR: dans la requête agrégée sans groupe par, l'expression n ° 1 de la liste de sélection contient une colonne non contenue 'c.f_name'; Ceci est incompatible avec sql_mode = seulement_full_group_by.


... et quand j'ajoute groupe par paramètre, cela donne ceci. Erreur: expression n ° 2 de la liste de sélection n'est pas en groupe par clause et contient la colonne non gré "C.L_Name" qui ne dépend pas fonctionnellement des colonnes du groupe par clause; Ceci est incompatible avec sql_mode = seulement_full_group_by.


3 Réponses :


0
votes

Vos requêtes existantes génèrent des erreurs car elles utilisent des fonctions agrégées ( somme () code>, comptent () code>) sans groupe code> clause de code> Toutes les colonnes non agrégées.

Pour résoudre votre besoin, une solution serait d'utiliser l'agrégation conditionnelle: p>

  • Récupérez toutes les transactions sur lesquelles l'e-mail du client apparaît dans le em_paid_to code> ou dans la clause em_paid_by code> clause li>
  • Groupe par le client (une option sensible consiste à ajouter l'ID client au groupe Groupe par CODE> Clause, eventHough Il ne fait pas partie des résultats) LI>
  • Les comptes et les sommes conditionnels conditionnels, selon que les enregistrements ont été assortis sur em_paid_to code> ou em_paid_by code> li> ul>

    La requête suivante vous donne des informations détaillées (nombre de paiements de et à, des montants payés par et à l'équilibre), vous pouvez choisir ce qui est pertinent pour vous: P>

    SELECT 
        c.f_name, 
        c.l_name, 
        SUM(c.email = t.em_paid_by) count_paid_by, 
        SUM(c.email = t.em_paid_to) count_paid_to, 
        SUM(CASE WHEN c.email = t.em_paid_by THEN t.amound ELSE 0 END) total_paid_by,
        SUM(CASE WHEN c.email = t.em_paid_to THEN t.amound ELSE 0 END) total_paid_to,
        SUM(CASE WHEN c.email = t.em_paid_by THEN t.amound ELSE -1 * t.amount END) balance
    FROM 
        customer c 
        INNER JOIN transaction t
            ON c.email IN (t.em_paid_by, t.em_paid_to)
    GROUP BY 
        c.cust_id, 
        c.f_name, 
        c.l_name
    ;
    


0 commentaires

0
votes

J'aciterais les données et l'agrégat:

select email, sum(amount)
from cusomer c join
     ((select em_paid_by as email, -amount as amount
       from transaction t
      ) union all
      (select em_paid_to, amount
       from transaction t
      )
     ) t
     on c.email = t.email
group by t.email, c.fname, c.lname;


0 commentaires

0
votes

J'utiliserais des sous-requêtes corrélées dans la clause SELECT:

select c.*,
    p.cnt_paid,
    r.cnt_received
    coalesce(p.sum_paid, 0) as sum_paid,
    coalesce(r.sum_received, 0) as sum_received,
    coalesce(p.sum_paid, 0) - coalesce(r.sum_received, 0) as paid_balance,
    p.cnt_paid + r.cnt_received as total_transactions
from customer c
left join (
    select em_paid_by as email, sum(amount) as sum_paid, count(*) as cnt_paid
    from transaction
    group by em_paid_by
) p on p.email = c.email
left join (
    select em_paid_to as email, sum(amount) as sum_received, count(*) as cnt_received
    from transaction
    group by em_paid_to
) r on r.email = c.email


0 commentaires