MySQL- Gruppierung von der Gruppierung

baserider

Well-known member
ID: 174417
L
10 März 2007
682
23
Hi,

ich habe eine Abfrage erstellt, in der ich auf die spalte Produktname gruppiert habe.
als ergebnis erhalte ich sowas:

produkt1 | hersteller1
produkt2 | hersteller1
produkt3 | hersteller1
produkt4 | hersteller2
produkt5 | hersteller2

jetzt möchte ich noch auf die spalte hersteller gruppieren. geht denn eine gruppierung auf eine vorherige gruppierung.
im endeffekt sollte dann immer der hersteller angezeigt werden und in klammern wie viele produkte es von diesem gibt.
 
im endeffekt sollte dann immer der hersteller angezeigt werden und in klammern wie viele produkte es von diesem gibt.

Wenn du nur das möchtest, wäre doch eine Abfrage über count sinnvoller??

Code:
COUNT(hersteller) FROM produkte WHERE hersteller = 1
 
im endeffekt sollte dann immer der hersteller angezeigt werden und in klammern wie viele produkte es von diesem gibt.

PHP:
SELECT hersteller, COUNT(*) FROM table GROUP BY hersteller

Du musst dich eben entscheiden, ob du die Anzahl der Produkte haben willst oder ob du ein bestimmtes Produkt haben willst.

Greetz

paddya
 
PHP:
SELECT hersteller, COUNT(*) FROM table GROUP BY hersteller

Du musst dich eben entscheiden, ob du die Anzahl der Produkte haben willst oder ob du ein bestimmtes Produkt haben willst.

Greetz

paddya

naja ich möchte die Anzahl der Produkte eines Herstellers anzeigen.
Aber so hat es jetzt funktioniert:

PHP:
SELECT t2.hersteller, count(t2.hersteller) FROM
  (SELECT c.produktname, k.hersteller, count(*)
     FROM table1 c, table2 k
     WHERE k.produktname = c.produktname
     GROUP BY c.produktname) as t2
GROUP BY t2.hersteller
 
naja ich möchte die Anzahl der Produkte eines Herstellers anzeigen.
Aber so hat es jetzt funktioniert:

PHP:
SELECT t2.hersteller, count(t2.hersteller) FROM
  (SELECT c.produktname, k.hersteller, count(*)
     FROM table1 c, table2 k
     WHERE k.produktname = c.produktname
     GROUP BY c.produktname) as t2
GROUP BY t2.hersteller

Hm...

PHP:
SELECT t2.hersteller, COUNT(t2.hersteller) FROM table2 AS t2 INNER JOIN table1 AS t1 ON t2.produktname = t1.produktname GROUP BY t2.hersteller

Sollte auch funktionieren. Mit entsprechenden Indizes ist das wesentlich performanter als deine Lösung.

Greetz

paddya
 
Hm...

PHP:
SELECT t2.hersteller, COUNT(t2.hersteller) FROM table2 AS t2 INNER JOIN table1 AS t1 ON t2.produktname = t1.produktname GROUP BY t2.hersteller

Sollte auch funktionieren. Mit entsprechenden Indizes ist das wesentlich performanter als deine Lösung.

Greetz

paddya

Das deine Abfrage performanter ist, da geb ich dir recht. Bei mir funktioniert das aber leider nicht so. Ich erhalte mit deiner Abfrage falsche Werte, da der Produktname bzw. (die ID) mehrmals in der zu verknüpfenden Tabelle (Produktbewertungen - und ein Produkt kann ja mehrere Bewertungen erhalten) vorkommen kann. Deswegen hatte ich vorhin auch geschrieben ich habe bereits eine Gruppierung gemacht.
 
Das deine Abfrage performanter ist, da geb ich dir recht. Bei mir funktioniert das aber leider nicht so. Ich erhalte mit deiner Abfrage falsche Werte, da der Produktname bzw. (die ID) mehrmals in der zu verknüpfenden Tabelle (Produktbewertungen - und ein Produkt kann ja mehrere Bewertungen erhalten) vorkommen kann. Deswegen hatte ich vorhin auch geschrieben ich habe bereits eine Gruppierung gemacht.

Dann dreh das Ganze um:

PHP:
SELECT p.hersteller, COUNT(p.hersteller) FROM produkte AS p INNER JOIN bewertungen AS b ON b.produktname = p.produktname GROUP BY p.hersteller

Das funktioniert dann auf jeden Fall: Das zählt alle Produkte, die eine Bewertung haben (was auch deine Intention war).

Greetz

paddya
 
Dann dreh das Ganze um:

PHP:
SELECT p.hersteller, COUNT(p.hersteller) FROM produkte AS p INNER JOIN bewertungen AS b ON b.produktname = p.produktname GROUP BY p.hersteller

Das funktioniert dann auf jeden Fall: Das zählt alle Produkte, die eine Bewertung haben (was auch deine Intention war).

Greetz

paddya

ich hatte deine Varianten auch schon probiert aber liefert falsche Ergebnisse.
Es ist schon richtig das deine Abfrage alle Produkte zählt, jedoch kann ein und dasselbe Produkt x-mal bewertet werden. Wenn von einem Hersteller Produkt 1 10 mal bewertet wurde und Produkt 2 20 mal, dann würde ja mit deiner Abfrage 30 rauskommen aber bei mir sollte dann ne 2 in klammern stehen, was meine Abfrage auch so ausgibt.
 
Verstehe ich Dich richtig, Du möchtest wissen, wieviele unterschiedliche Produkte eines Herstellers bewertet wurden ?
Und Du hast dazu eine Tabelle produkte mit den Spalten produktname(schlüssel) , hersteller , ...
Und eine Tabelle bewertungen mit den Spalten (schlüssel), produktname , bewertung

Dann versuch mal das:

PHP:
SELECT p.hersteller, COUNT(DISTINCT p.produktname) 
FROM produkte AS p INNER JOIN bewertungen AS b 
ON b.produktname = p.produktname 
GROUP BY p.hersteller  ;


das:

PHP:
SELECT p.hersteller, COUNT(*)
FROM produkte p
WHERE p.produktname IN
( SELECT b.produktname
FROM bewertungen b ) 
GROUP BY p.hersteller;


oder das:

PHP:
SELECT p.hersteller, COUNT(*)
FROM produkte p
WHERE EXISTS
( SELECT *
FROM bewertungen b 
WHERE b.produktname = p.produktname) 
GROUP BY p.hersteller;
 
Zuletzt bearbeitet:
Wenn von einem Hersteller Produkt 1 10 mal bewertet wurde und Produkt 2 20 mal, dann würde ja mit deiner Abfrage 30 rauskommen aber bei mir sollte dann ne 2 in klammern stehen, was meine Abfrage auch so ausgibt.

Das ist absolut unmöglich. Es wird jedes Produkt überprüft, ob es eine Bewertung hat. Hat es eine, wird es gezählt, ansonsten nicht.

Mit einem LEFT JOIN würde das wiederum anders aussehen. Aber hier habe ich explizit den INNER JOIN verwendet.

Greetz

paddya
 
Das ist absolut unmöglich. Es wird jedes Produkt überprüft, ob es eine Bewertung hat. Hat es eine, wird es gezählt, ansonsten nicht.

Mit einem LEFT JOIN würde das wiederum anders aussehen. Aber hier habe ich explizit den INNER JOIN verwendet.

Greetz

paddya

Warum sollte es denn unöglich sein? Ich habe deine Abfrage ausprobiert und komme zu den falschen Ergebnissen.
In der DB gibt es 3 Produkte vom gleichen Hersteller, welche Bewertungen erhalten haben. Produkt1 wurde 2 mal bewertet, Produkt2 wurde 5 mal bewertet und Produkt3 wurde 3 mal bewertet. als Ergebnis erhalte ich 10 und nicht wie gewünscht 3
 
Verstehe ich Dich richtig, Du möchtest wissen, wieviele unterschiedliche Produkte eines Herstellers bewertet wurden ?
Und Du hast dazu eine Tabelle produkte mit den Spalten produktname(schlüssel) , hersteller , ...
Und eine Tabelle bewertungen mit den Spalten (schlüssel), produktname , bewertung

genau so meinte ich es

PHP:
SELECT p.hersteller, COUNT(*)
FROM produkte p
WHERE p.produktname IN
( SELECT b.produktname
FROM bewertungen b ) 
GROUP BY p.hersteller;

diese Abfrage bringt mir das gewünschte Ergebnis lief bei mir aber auch nicht schneller als meine Abfrage, ist jedoch nen stück kürzer als meine Lösung.

Ich versteh nur dieses Subselect in der WHERE-Klausel noch nicht so ganz, da wäre ich nicht drauf gekommen.
 
Warum sollte es denn unöglich sein? Ich habe deine Abfrage ausprobiert und komme zu den falschen Ergebnissen.
In der DB gibt es 3 Produkte vom gleichen Hersteller, welche Bewertungen erhalten haben. Produkt1 wurde 2 mal bewertet, Produkt2 wurde 5 mal bewertet und Produkt3 wurde 3 mal bewertet. als Ergebnis erhalte ich 10 und nicht wie gewünscht 3

Edit: Natürlich... ich hab nen tollen Cross-JOIN gebastelt und es ist mir erst gerade aufgefallen. Sorry für die Aufregung...

Greetz

paddya
 
Zuletzt bearbeitet:
ich habe genau so eine Struktur wie du es geschrieben hast.
Achja was nen Join macht is mir schon klar :)

Wenn ich mal von deiner Tabelle ausgehe, dann bekommst du 3 Datensätze wenn das produkt 3 mal in den bewertungen ist, das gruppiert ergibt mi nem count 3 und nicht 1 :)
 
Dann will ich mal alles wieder gut machen :)

kein Problem. Ich versteh leider die 2. Abfrage von Transversalis nicht so ganz was dort abläuft, aber funktioniert ebenfalls.

PHP:
SELECT p.hersteller, COUNT(*)
FROM produkte p
WHERE p.produktname IN
( SELECT b.produktname
FROM bewertungen b ) 
GROUP BY p.hersteller;

MySQL iteriert durch alle Datensätze der Produkttabelle und prüft durch eine Subquery, ob der Produktname in der Liste der bewerteten Produkte ist.

Das hier könnte bei vielen Bewertungen und richtigen Indizes eine kleine Optimierung sein.

PHP:
SELECT p.hersteller, COUNT(*)
FROM produkte p
WHERE (SELECT b.produktname
FROM bewertungen b WHERE b.produktname = p.produktname LIMIT 1) IS NOT NULL 
GROUP BY p.hersteller;

Greetz

paddya
 
Zuletzt bearbeitet:
ja, jetzt versteh ich was da abläuft. naja man lernt nie aus. auf die abfrage wär ich nicht gekommen :) und ist doch fast 30% schneller.

aber trotzdem danke für die hilfe :)