ich hab hier anscheinend wieder einen Wunsch an eine MySQL Tabelle, und
steh grad bei der Lᅵsung aufn Schlauch.
Ich habe eine Tabelle mit Produkten, die in Kategorien unterteilt sind.
Ich mᅵchte nun ein SELECT ᅵber diese Produkte, welche nur maximal drei
Produkte pro Kategorie ausgibt. (Sozusagen als Beispiele fuer die
Kategorien).
Gibt es eine Mᅵglichkeit, nach einem count() in der gleichen Kategorie
andere Produkte einfach auszublenden?
SELECT p.name, p.category
FROM products p
WHERE ...
ORDER BY p.sorting
Das WHERE ... ist mir in diesem Zusammenhang vᅵllig unklar. Ich weiss,
dass es Funktionen wie count() oder max() gibt und auch die Schlagworte
HAVING etc. Nur komm ich grad gar nicht dahinter, wie ich das am besten
anfangen kann.
Fᅵr einen Denkanstoᅵ, wᅵre ich dankbar.
Viele Grᅵᅵe,
Sebastian
Dazu eignen sich CTE-Funktionen wie row_number() over (...) :
test=*# select * from products ;
name | category
--------+----------
name11 | 1
name12 | 1
name13 | 1
name14 | 1
name15 | 1
name21 | 2
name22 | 2
name23 | 2
name24 | 2
(9 rows)
test=*# select category, name, row_number() over (partition by category) from products ;
category | name | row_number
----------+--------+------------
1 | name11 | 1
1 | name12 | 2
1 | name13 | 3
1 | name14 | 4
1 | name15 | 5
2 | name21 | 1
2 | name22 | 2
2 | name23 | 3
2 | name24 | 4
(9 rows)
test=*# select category, name from (select category, name, row_number() over (partition by category) from products) foo where row_number <=3 ;
category | name
----------+--------
1 | name11
1 | name12
1 | name13
2 | name21
2 | name22
2 | name23
(6 rows)
Die schlechte Nachricht fᅵr Dich: hat MySQL noch nicht.
Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Hallo Andreas,
bis hierhin hab ich mich gefreut, dass du selbst an einem Beispiel genau
das, was ich suche, erfolgreich lᅵsen konntest. Vielen Dank fᅵr die
Aufklᅵrung, dass es so mit anderen DBMS funktionieren kann. Wie du schon
festgestellt hast, ist diese Lᅵsung fᅵr meine Problemstellung nicht
relevant.
Viele Grᅵᅵe,
Sebastian
--
Obligatorischer Witz (OJ):
Ein Mann fliegt einen Heiᅵluftballon und bemerkt, dass er die
Orientierung verloren hat. Er reduziert seine Hᅵhe und macht schlieᅵlich
einen Mann am Boden aus. Er lᅵsst den Ballon noch weiter sinken und
ruft: "Entschuldigung, kᅵnnen Sie mir helfen? Ich versprach meinem
Freund, ihn vor einer halben Stunde zu treffen, aber ich weiᅵ nicht, wo
ich mich befinde!"
Der Mann am Boden sagt: "Ja. Sie befinden sich in einem Heiᅵluftballon.
Ihre Position ist zwischen 40 und 42 Grad nᅵrdliche Breite, und zwischen
58 und 60 Grad westliche Lᅵnge."
"Sie mᅵssen Ingenieur sein", sagt der Ballonfahrer.
"Bin ich", antwortet der Mann. "Woher haben Sie das gewusst?"
"Sehen Sie", sagt der Ballonfahrer, "alles, was Sie mir gesagt haben,
ist technisch korrekt, aber ich habe keine Ahnung, was ich mit den
Informationen anfangen soll, und ich weiᅵ immer noch nicht, wo ich bin."
Der Ingenieur sagt daraufhin: "Sie mᅵssen ein Manager sein."
"Bin ich", antwortet der Ballonfahrer, "woher haben Sie das gewusst?"
"Sehen Sie", sagt der Ingenieur, "Sie wissen nicht, wo Sie sind, oder
wohin Sie gehen. Sie haben ein Versprechen gegeben, von dem Sie keine
Ahnung haben, wie Sie es einhalten kᅵnnen, und Sie erwarten, dass ich
Ihnen dieses Problem lᅵse. Tatsache ist: Sie befinden sich in exakt
derselben Position, in der Sie waren, bevor wir uns getroffen haben,
aber irgendwie ist jetzt alles meine Schuld."
Naja, vielleicht als Anregung, ᅵber einen Wechsel zu PostgreSQL
nachzudenken? Das ist das, was ich da verwendet habe.
Um diese Aufgabe zu lᅵsen braucht man kein PostgreSQL.
ᅵbrigens Sebastian, guter "Obligatorischer Witz (OJ)" - und so treffend ;)
Das hier sollte gehen, den Ansatz hast du ja bereits in deinem
Eingangspost richtig vermutet (mit having):
SELECT p.name, p.category, COUNT(p.category) AS summe
FROM products p
GROUP BY p.category
HAVING summe <= 3
ORDER BY p.sorting;
Gruᅵ
Steffen
> Um diese Aufgabe zu lösen braucht man kein PostgreSQL.
Nö, da inzwischen die meisten DBMS OLAP-Funktionen wie ROW_NUMBER kennen.
Bei Andreas Query fehlt übrigens das ORDER BY, da werden die meisten
anderen DBMS meckern. Und ein Alias für die row_number fehlt auch :-)
> Das hier sollte gehen, den Ansatz hast du ja bereits in deinem
> Eingangspost richtig vermutet (mit having):
>
> SELECT p.name, p.category, COUNT(p.category) AS summe
> FROM products p
> GROUP BY p.category
> HAVING summe<= 3
> ORDER BY p.sorting;
Nö, das liefert alle Kategorien mit maximal 3 Rows, aber nicht maximal 3
Rows von allen Kategorien.
Die klassische Lösung ist ein non-equi-join, der den count berechnet,
die Performance ist bei größeren Mengen aber absolut tödlich:
select category, name,
(select count(*) from products as p2
where p.category = p2.category
and p.sorting <= p2.sorting -- p.sorting muss eindeutig sein
) as x
from products as p
where x <= 3
Dieter