8
votes

En utilisant plusieurs jointures. Somme () produisant une mauvaise valeur

Je reçois des informations de base de la facture dans une requête SQL et de déterminer le total des commandes et des totaux de paiement dans la même requête. Voici ce que j'ai jusqu'à présent:

SELECT
    orders.billerID, 
    orders.invoiceDate, 
    orders.txnID, 
    orders.bName, 
    orders.bStreet1, 
    orders.bStreet2, 
    orders.bCity, 
    orders.bState, 
    orders.bZip, 
    orders.bCountry, 
    orders.sName, 
    orders.sStreet1, 
    orders.sStreet2, 
    orders.sCity, 
    orders.sState, 
    orders.sZip, 
    orders.sCountry, 
    orders.paymentType, 
    orders.invoiceNotes, 
    orders.pFee, 
    orders.shipping, 
    orders.tax, 
    orders.reasonCode, 
    orders.txnType, 
    orders.customerID, 
    customers.firstName AS firstName, 
    customers.lastName AS lastName, 
    customers.businessName AS businessName, 
    orderStatus.statusName AS orderStatus, 
    SUM((orderItems.itemPrice * orderItems.itemQuantity))
      + orders.shipping + orders.tax AS orderTotal, 
    SUM(payments.amount) AS totalPayments                       <-- this sum
FROM
    orders 
    LEFT JOIN customers ON orders.customerID = customers.id 
    LEFT JOIN orderStatus ON orders.orderStatus = orderStatus.id
    LEFT JOIN payments ON payments.orderID = orders.id          <-- this join
    LEFT JOIN orderItems ON orderItems.orderID = orders.id 


1 commentaires

Bonjour, et bienvenue à Stackoverflow. Pour formater le code, comme SQL, sélectionnez-le et appuyez sur Ctrl + K, cela tiendra le bloc de 4 espaces, qui sera interprété par les scripts sur ce site pour signifier le code et sera ainsi reformaté en conséquence.


3 Réponses :


22
votes

Si vous exécutez la requête sans un groupe par , vous verrez que certains paiements ont plusieurs rangées. C'est parce que vous rejoignez également des articles de commande. L'ensemble de résultats contiendra une ligne pour chaque combinaison de commande et paiement.

Une solution serait de modifier la somme à: xxx

Cela garantirait les paiements avec plusieurs Les ordonnances ne sont pas résumées plusieurs fois.


4 commentaires

Fait un sens! Merci pour la réponse rapide +1!


Je pense que cela vient d'avoir sauvé ma journée


C'est une bonne solution lorsque vous souhaitez utiliser Join (qui retourne plusieurs rangées) et somme


C'est une sous-requête corrélée qui est beaucoup plus lente.



0
votes

Je suppose que le paiement est de 10 $ et il y a deux éléments dans l'ordre (Table de commande). Si tel est le cas, essayez d'utiliser un groupe sur les commandes / clients / orderstatus.


0 commentaires

0
votes

Une solution consiste à faire des requêtes imbriquées pour chaque référence code> code>. Il devrait être beaucoup plus rapide que d'utiliser une requête corrélée (suggérée par Andomar) et fonctionnera pour les systèmes de base de données conformes à la norme ANSI SQL.

Exemple non testé: P>

SELECT
  orders_with_payments.billerID,
  orders_with_payments.invoiceDate,
  orders_with_payments.totalPayments,
  SUM(orderItems.itemPrice) AS orderTotal,
  ...
FROM (
  SELECT
    orders.billerID,
    orders.invoiceDate,
    SUM(payments.amount) AS totalPayments,
    ...
  FROM orders
  LEFT JOIN payments ON payments.orderID = orders.id
) orders_with_payments
LEFT JOIN orderItems ON orderItems.orderID = orders_with_payments.id


0 commentaires