2017-04-12 1 views
0

Ich habe drei Tabellendrei Tabellen mit Summen Füge- und zählt

[Benutzer]

id 
name 
email 

[Transaktionen]

id 
user_id 
amount 
points_rewarded 

[Rücknahme]

id 
user_id 
points_redeemed 

Ich möchte die Datenbank abzufragen die folgenden Felder

users.id 
users.name 
transactions // Number of transactions 
redemptions // Number of redemptions 
points   // Sum of points_rewarded - sum of points_redeemed 

Ich kann entweder bekommen verwalten zu Transaktionen oder Tilgungen mit den Nutzern Tisch sitzen, aber ich kann nicht alle drei in einer Abfrage zu verbinden scheinen.

[users + Transaktionen]

SELECT users.id,users.name,COUNT(transactions.id) AS transactions,SUM(transactions.points_rewarded) AS points_rewarded FROM users LEFT JOIN transactions ON users.id=transactions.user_id GROUP BY users.id, users.name 

Welche die richtigen Werte für users.id, users.name, Transaktionen und points_rewarded gibt.

[users + Rücknahme]

SELECT users.id,users.name,COUNT(redemptions.id) AS redemptions, IFNULL(SUM(redemptions.points_redeemed),0) AS points_redeemed FROM users LEFT JOIN redemptions ON users.id=redemptions.user_id GROUP BY users.id, users.name 

Welche die richtigen Werte für users.id, users.name, Rücknahmen gibt und points_redeemed.

Wenn ich links einfach beide kommen mit

SELECT users.id,users.name,COUNT(transactions.id) AS transactions,COUNT(redemptions.id) AS redemptions,SUM(transactions.points_rewarded) - IFNULL(SUM(redemptions.points_redeemed),0) AS points FROM users LEFT JOIN transactions ON users.id=transactions.user_id LEFT JOIN redemptions on users.id=redemptions.user_id GROUP BY users.id, users.name 

ich falsche Werte für die Rücknahme Spalten erhalten. Ich bekomme im Grunde alle point_rewards Werte multipliziert mit der Gesamtzahl der Rücknahmen, wodurch die Punkte (points_rewarded - points_redeemed) negative Werte sind, was nicht möglich ist.

Jede Hilfe wäre großartig!

Antwort

0

Ja es ist, weil links Willen Rückkehr eine Vereinigung von Datensätzen verbindet, die die Summen verändern können, die sonst sollte und unabhängig voneinander auf jeden Satz gelten würde (wie es funktioniert, wenn Sie zwei separate Abfragen verwenden)

Also ja, beide Anfragen müssen noch in einer „Master“ Abfrage koexistieren:

SELECT users.id, 
     users.name, 
     t.transactions, 
     r.redemptions, 
     t.points_rewarded - r.points_redeemed AS points 
FROM users 
     LEFT JOIN (
     SELECT 
      users.id, 
      COUNT(*) AS transactions, 
      COALESCE(SUM(transactions.points_rewarded),0) AS points_rewarded 
     FROM users LEFT JOIN transactions ON users.id=transactions.user_id 
     GROUP BY users.id 
     ) t ON users.id = t.user_id 
     LEFT JOIN (
     SELECT 
      users.id, 
      COUNT(*) AS redemptions, 
      COALESCE(SUM(redemptions.points_redeemed),0) AS points_redeemed 
     FROM users LEFT JOIN redemptions ON users.id=redemptions.user_id 
     GROUP BY users.id 
     ) r ON users.id = r.user_id 
; 
0

Basierend auf Sebas Antwort die letzte Abfrage, die ich mit ist gegangen:

SELECT 
    users.id, 
    users.name, 
    COALESCE(t.transactions,0) AS transactions, 
    COALESCE(t.points_rewarded,0) AS points_rewarded, 
    COALESCE(r.redemptions,0) AS redemptions, 
    COALESCE(r.points_redeemed,0) AS points_redeemed, 
    COALESCE(t.points_rewarded,0)-COALESCE(r.points_redeemed,0) AS points 
    FROM users 
    LEFT JOIN (
     SELECT 
     users.id, 
     transactions.user_id, 
     COALESCE(COUNT(transactions.id),0) AS transactions, 
     COALESCE(SUM(transactions.points_rewarded),0) AS points_rewarded 
     FROM users 
     LEFT JOIN transactions ON users.id=transactions.user_id 
     GROUP BY users.id) t 
    ON users.id=t.user_id 
    LEFT JOIN (
     SELECT 
     users.id, 
     redemptions.user_id, 
     COALESCE(COUNT(redemptions.id),0) AS redemptions, 
     COALESCE(SUM(redemptions.points_redeemed),0) AS points_redeemed 
     FROM users LEFT JOIN redemptions ON users.id=redemptions.user_id 
     GROUP BY users.id) r 
    ON users.id=r.user_id 

Jetzt ein ll, das übrig bleibt, verwandelt dies in etwas "eloquenteres" ;-)