2016-04-12 10 views
1

Ich habe drei Tabellen:MySQL Query - SUM von COUNT aus mehreren Tabellen

  • Kunden: id, name
  • contracts_jewels: id, customer_id, bezahlt, übertragen, final_date
  • contracts_objects: id, customer_id, bezahlt, übertragen, final_date

Wie Sie sehen, ist die Struktur der letzten beiden Tabellen identisch. Die „bezahlt“ und die „übertragen“ Felder den Wert 0 oder 1 enthalten

Was ich brauche, ist eine Abfrage zu machen, die alle Kunden zurückgeben sollte (ganz gleich, ob sie Verträge haben oder nicht) und für jeden Kunden: id, name, count_contracts_all, count_contracts_active

wo:

  • count_contracts_all würde die Summe von [SELECT COUNT (*) FROM contracts_jewels WHERE customer_id = 3 (zum Beispiel)] bedeuten, und [ COUNT (*) FROM contracts_objects SELECT WHERE customer_id = 3 (zum Beispiel)]
  • count_contracts_active würde die Summe der mean [SELECT COUNT (*) FROM contracts_jewels WHERE customer_id = 3 und final_date> = Now() und bezahlt = 0 uND übertragen = 0] und [SELECT COUNT (*) FROM contracts_objects WHERE customer_id = 3 UND final_date> = Jetzt() UND bezahlt = 0 UND übertragen = 0]

Irgendeine Idee? Würden Sie mir bitte helfen? Vielen Dank!

+0

Ich denke, eine UNION Ihnen helfen können: SELECT field_1 [, field_2, ...] VON table_1 [, table_2, ...] UNION [ALL] SELECT Field_A [, Field_B, ...] VON TABLE_A [ , table_b, ...]; ' – Holger

Antwort

0

Sie können die Verträge separat zählen und sie dann einfach an den Kunden verbinden:

SELECT 
    c.id, 
    COALESCE(oc.active_count,0) + COALESCE(jc.active_count,0) as count_contracts_active, 
    COALESCE(oc.total_count,0) + COALESCE(jc.total_count,0) as count_contracts_all 
FROM customers c 
LEFT JOIN (
    SELECT 
     customer_id 
     COUNT(*) as total_count, 
     COUNT(IF(final_date>=Now() AND paid=0 AND transferred=0,1,NULL)) as active_count 
    FROM contracts_jewels 
    GROUP BY customer_id 
) as oc ON oc.customer_id = c.id 
LEFT JOIN (
    SELECT 
     customer_id 
     COUNT(*) as total_count, 
     COUNT(IF(final_date>=Now() AND paid=0 AND transferred=0,1,NULL)) as active_count 
    FROM contracts_objects 
    GROUP BY customer_id 
) as jc ON jc.customer_id = c.id 
+0

Es geht wie ein Zauber! Vielen Dank! Ich fürchte, ich kann Ihre Antwort nicht bewerten, ich bin ein neuer Benutzer hier, aber ich bin sehr dankbar! – fortitude23

+0

@ fortitude23: Sie können noch nicht bewerten, aber Sie können immer noch die Antwort "akzeptieren", wenn es Ihnen geholfen hat, Ihr Problem zu lösen – Preuk

0

Eine schnelle Lösung, die ich jetzt richtig denken kann, ist:

SELECT COUNT(`temp_table`.*) FROM (
    SELECT * FROM contracts_jewels WHERE customer_id=3 UNION ALL 
    SELECT * FROM contracts_objects WHERE customer_id=3) AS `temp_table` 

UND

SELECT COUNT(`temp_table`.*) FROM (
SELECT * FROM contracts_jewels WHERE customer_id=3 AND final_date>=Now() AND paid=0 AND transferred=0 UNION ALL 
    SELECT * FROM contracts_objects WHERE customer_id=3 AND final_date>=Now() AND paid=0 AND transferred=0) AS `temp_table` 
0

Sie können jede dieser Tabellen zweimal verbinden und ihre entsprechenden COUNT s hinzufügen Ihr Ergebnis:

SELECT 
    c.id, 
    (COUNT(cj1.id)+COUNT(co1.id)) AS count_contracts_all, 
    (COUNT(cj2.id)+COUNT(co2.id)) AS count_contracts_active 
FROM 
    customers c 
    LEFT OUTER JOIN contracts_jewels cj1 ON c.id = cj1.customer_id 
    LEFT OUTER JOIN contracts_objects co1 ON c.id = co1.customer_id 
    LEFT OUTER JOIN contracts_jewels cj2 ON 
     c.id = cj2.id AND 
     cj2.final_date >= NOW() AND 
     cj2.paid = 0 AND 
     cj2.transferred = 0 
    LEFT OUTER JOIN contracts_object co2 ON 
     c.id = co2.id AND 
     co2.final_date >= NOW() AND 
     co2.paid = 0 AND 
     co2.transferred = 0 
GROUP BY c.id 

Hinweis: Ich habe das nicht ausgeführt, aber hoffentlich bringt es Sie in die richtige Richtung.