Einfache und schnelle Frage, ich habe diese Tabellen:
//table people
| pe_id | pe_name |
| 1 | Foo |
| 2 | Bar |
//orders table
| ord_id | pe_id | ord_title |
| 1 | 1 | First order |
| 2 | 2 | Order two |
| 3 | 2 | Third order |
//items table
| item_id | ord_id | pe_id | title |
| 1 | 1 | 1 | Apple |
| 2 | 1 | 1 | Pear |
| 3 | 2 | 2 | Apple |
| 4 | 3 | 2 | Orange |
| 5 | 3 | 2 | Coke |
| 6 | 3 | 2 | Cake |
Ich muss eine Abfrage haben, in der alle Personen aufgeführt sind, die Anzahl der Bestellungen und die Anzahl der total - Elemente wie folgt:
| pe_name | num_orders | num_items |
| Foo | 1 | 2 |
| Bar | 2 | 4 |
Aber ich kann es nicht zum Laufen bringen! Ich habe es versucht
SELECT
people.pe_name,
COUNT(orders.ord_id) AS num_orders,
COUNT(items.item_id) AS num_items
FROM
people
INNER JOIN orders ON (orders.pe_id = people.pe_id)
INNER JOIN items ON items.pe_id = people.pe_id
GROUP BY
people.pe_id;
Dies gibt jedoch die num_*
-Werte falsch zurück:
| name | num_orders | num_items |
| Foo | 2 | 2 |
| Bar | 8 | 8 |
Ich habe bemerkt, dass es funktioniert, wenn ich versuche, mich zu einem Zeitpunkt einer Tabelle anzuschließen:
SELECT
people.pe_name,
COUNT(orders.ord_id) AS num_orders
FROM
people
INNER JOIN orders ON (orders.pe_id = people.pe_id)
GROUP BY
people.pe_id;
//give me:
| pe_name | num_orders |
| Foo | 1 |
| Bar | 2 |
//and:
SELECT
people.pe_name,
COUNT(items.item_id) AS num_items
FROM
people
INNER JOIN items ON (items.pe_id = people.pe_id)
GROUP BY
people.pe_id;
//output:
| pe_name | num_items |
| Foo | 2 |
| Bar | 4 |
Wie kombiniere ich diese beiden Abfragen in einer?
Es ist sinnvoller, den Artikel mit den Bestellungen zu verbinden als mit den Leuten!
SELECT
people.pe_name,
COUNT(distinct orders.ord_id) AS num_orders,
COUNT(items.item_id) AS num_items
FROM
people
INNER JOIN orders ON orders.pe_id = people.pe_id
INNER JOIN items ON items.ord_id = orders.ord_id
GROUP BY
people.pe_id;
Das Zusammenfügen der Gegenstände mit den Menschen provoziert viele Dublonen. Zum Beispiel werden die Kuchenstücke in Auftrag 3 mit dem Auftrag 2 über den Join zwischen den Leuten verknüpft, und Sie möchten nicht, dass dies geschieht !!
So :
1- Sie benötigen ein gutes Verständnis Ihres Schemas. Artikel sind Links zu Bestellungen und nicht zu Personen.
2- Sie müssen unterschiedliche Bestellungen für eine Person zählen, ansonsten zählen Sie so viele Artikel wie Bestellungen.
Wie Frank darauf hingewiesen hat, müssen Sie DISTINCT verwenden. Da Sie zusammengesetzte Primärschlüssel verwenden (was vollkommen in Ordnung ist), müssen Sie auch sicherstellen, dass Sie den gesamten Schlüssel in Ihren Joins verwenden:
SELECT
P.pe_name,
COUNT(DISTINCT O.ord_id) AS num_orders,
COUNT(I.item_id) AS num_items
FROM
People P
INNER JOIN Orders O ON
O.pe_id = P.pe_id
INNER JOIN Items I ON
I.ord_id = O.ord_id AND
I.pe_id = O.pe_id
GROUP BY
P.pe_name
Ohne I.ord_id = O.ord_id wurde jede Artikelzeile mit jeder Bestellzeile einer Person verbunden.
ich habe versucht, für beide, count (distinkte ord.ord_id) als num_order, count (distinkte Elemente.item_id) als num-Elemente zu setzen
es funktioniert :)
SELECT
people.pe_name,
COUNT(distinct orders.ord_id) AS num_orders,
COUNT(distinct items.item_id) AS num_items
FROM
people
INNER JOIN orders ON (orders.pe_id = people.pe_id)
INNER JOIN items ON items.pe_id = people.pe_id
GROUP BY
people.pe_id;
Danke für den Thread es hilft :)
select pe_name,count( distinct b.ord_id),count(c.item_id)
from people a, order1 as b ,item as c
where a.pe_id=b.pe_id and
b.ord_id=c.order_id group by a.pe_id,pe_name
Ihre Lösung ist nahezu korrekt. Sie könnten DISTINCT hinzufügen:
SELECT
people.pe_name,
COUNT(distinct orders.ord_id) AS num_orders,
COUNT(items.item_id) AS num_items
FROM
people
INNER JOIN orders ON (orders.pe_id = people.pe_id)
INNER JOIN items ON items.pe_id = people.pe_id
GROUP BY
people.pe_id;
Man muss verstehen, was ein JOIN oder eine Reihe von JOINs mit einem Datensatz macht. Mit dem Beitrag von strae erhalten Sie mit einer pe_id von 1, die mit der entsprechenden Reihenfolge und den Elementen in pe_id = 1 verknüpft ist, folgende Daten, aus denen Sie auswählen können:
[Tabelle Personen Teil] [Tabelle Bestellungen Teil] [Tabelle Artikel Teil]
| people.pe_id | people.pe_name | orders.ord_id | orders.pe_id | orders.ord_title | item.item_id | item.ord_id | item.pe_id | item.title |
| 1 | Foo | 1 | 1 | Erster Auftrag | 1 | 1 | 1 | Apple |
| 1 | Foo | 1 | 1 | Erster Auftrag | 2 | 1 | 1 | Birne |
Die Verbindungen haben im Wesentlichen ein kartesisches Produkt aller Tische. Im Grunde haben Sie diesen Datensatz zur Auswahl, weshalb Sie eine eindeutige Zählung für orders.ord_id und items.item_id benötigen. Andernfalls führen beide Zählungen zu 2 - weil Sie tatsächlich zwei Zeilen zur Auswahl haben.