2017-07-17 7 views
1

Ich habe eine Sammlung von Tabellen in einer relationalen DatenbankSQL - Zählen mit verschachtelter Unterabfrage

  • products
  • categories
  • orders
  • line_items
  • customers

Produkte haben eine Viele-zu-Viele-Beziehung mit Kategorien (Join-Tabelle categories_products) und hat auch viele orders bis line_items, die eine Join-Tabelle für products und orders mit einer ID ist. A customer hat auch viele orders.

Ich versuche, einige SQL zusammen zu stellen, die mir diese Art von Antwort geben:

customer_id | customer_first_name | category_id | category_name | number_purchased 
    ----------------------------------- 
    1 |Jack | 1 | Electronics | 15 
    2 |Jill | 1 | Electronics | 2 
    2 |Jill | 2 | Hiking | 3 

Dies ist die riesigen Brocken von SQL Ich habe diese Werte zu erhalten, zu verwenden versucht:

SELECT 
      DISTINCT customers.id AS customer_id, 
      customers.first_name AS customer_first_name, 
      categories.id AS category_id, 
      categories.name AS category_name, 
      (
       SELECT count(li.id) FROM line_items li 
       INNER JOIN orders o ON li.order_id = o.id 
       INNER JOIN products p ON li.product_id = p.id 
       INNER JOIN categories_products cp ON cp.product_id = p.id 
       WHERE 
        o.customer_id = customer_id 
        AND o.status = 3 
        AND cp.category_id = category_id 
      ) AS number_purchased 
     FROM orders 
     LEFT JOIN customers ON orders.customer_id = customers.id 
     LEFT JOIN line_items li ON li.order_id = orders.id 
     LEFT JOIN products ON products.id = li.product_id 
     LEFT JOIN categories_products catpr ON catpr.product_id = products.id 
     LEFT JOIN categories ON catpr.category_id = categories.id 

Nur die Zählung selbst ist falsch. Anstatt die Anzahl der Werbebuchungen zu ermitteln, die ein Kunde in einer bestimmten Kategorie gekauft hat, erhalte ich stattdessen eine Zählung für alle LineItems, die Teil einer abgeschlossenen Bestellung waren.

Wie kann ich die Anzahl der line_items, die von einer bestimmten customer innerhalb einer category gekauft wurde, korrekt darstellen?

HINWEIS: Im SQL-Text verwendet o.status = 3 eine Aufzählung, um anzugeben, dass eine Bestellung "abgeschlossen" ist.

+0

Ihre Abfrage sieht aus wie es spezifisch für Kategorie ist. Wird beim Entfernen von 'number_purchased' eine ähnliche Ausgabe zurückgegeben? –

+0

Ich empfehle das Hinzufügen von Gruppen von –

+0

@RudyM 'number_purchased' ist der einzige Wert, der falsch zurückgegeben wird. Ich könnte theoretisch den 'number_purchased' Wert in separaten Abfragen für jede Kombination von' customer' und 'category' oder auf der Codeebene erhalten, aber ich versuche speziell eine einzige SQL-Anweisung zu schreiben, um alle diese Informationen korrekt auszugeben – PapaPoison

Antwort

0

Ich denke, Ihre innere Verbindung mit categories_products ist dies vermasseln. Sie sollten eine Geige einrichten, wie @Strawberry vorgeschlagen, oder versuchen Sie dies:

+1

Okay, dieser Kommentar hat mich am meisten dorthin gebracht. Ein zusätzliches Detail, das mir dabei geholfen hat, war, dass ich in der Unterabfrage 'customer_id' verwendet habe. Das Ersetzen durch die ursprüngliche "customers.id" stellte stattdessen sicher, dass die korrekten Werte an die Unterabfrage übergeben wurden. – PapaPoison

0

Wenn Sie Ihre Anzahl korrigieren möchten, würde ich empfehlen, eine GROUP BY-Klausel in der Unterabfrage zu verwenden. Wenn Sie GROUP BY-Bestellungen haben, erhalten Sie nur die spezifische Bestellung, die Sie erhalten haben, als Sie nachgesehen haben, dass die Benutzer-ID korrekt war. Ich möchte Sie ermutigen, einen Blick auf Fehler in anderen Teilen Ihres SQL-Codes zu werfen, um diese große Anfrage zu bereinigen. Stellen Sie beispielsweise sicher, dass Sie distinct verwenden möchten und dass Sie tatsächlich Links-Joins und Inner-Joins verwenden möchten, die beide die Leistung Ihres Programms ernsthaft beeinträchtigen könnten.

+0

Was meinen Sie, wenn Sie GROUP BY Bestellungen sagen? Ich habe eine GROUP BY-Anweisung zur Unterabfrage hinzugefügt ('GROUP BY o.id '), was die _first_ count korrekt macht, aber jede nachfolgende Zeile verwendet fälschlicherweise die gleiche Anzahl. Zum Beispiel hat 'customer1' eine Bestellung mit 3' line_items'/'products' mit der' category' "Electronics". Die Spalte "number_purchased" wird als 3 gezählt - richtig für diese erste Zeile. "Customer2" hat jedoch einen Auftrag, der 2 'line_items' /' products' mit den 'category'" Books "enthält. Die Zählung kommt immer noch als 3 zurück, wenn es 2 sein sollte. Gibt es einen Einblick? – PapaPoison