Mehrfacheinträge ausgeben mittels count: Optimierung möglich?

sony1980

Neuer Benutzer
Beiträge
2
Hallo zusammen,

ich habe bereits gesucht und leider nicht die passende Lösung gefunden ( oder ich wusste nicht, wie ich die passenden Stichwörter formulieren sollte)
ich habe folgenden Sachverhalt (vereinfacht dargestellt).
Ich habe eine Tabelle mit Bestellungen. Diese enthält die Person_id und die bestell_id. eine Person ( Person_id) kann mehrere bestellungen ( mehrere bestell_ids) haben. Die bestell_ids sind unique in der Tabelle Bestellungen.
Nun will ich eine Liste ausgeben lassen nur mit Personen (person_ids) die mehrere Bestellungen haben

gibt es eine elegantere Variante als diese Abfrage

SELECT b.person_id, s.name, s.vorname, b.bestell_id, b.bestelldatum,
from bestellungen as b

inner join person as s
ON (b.person_id = s.person_id)

where b.person_id
IN (SELECT person_id
FROM bestellungen
where ( bedingung)
GROUP BY person_id
HAVING (COUNT(person_id) > 1) )

Ergebnis wäre
person_id bestellid
101 1
101 2
303 15
303 17
303 18

cool wäre es, wenn ich auch die Anzahl der Bestellungen pro Person ausgeben lassen könnte

person_id bestellid Anzahl
101 1 2
101 2 2
303 15 3
303 17 3
303 18 3

Dazu habe ich die Abfrage so angepasst. Kann man das irgendwie optimieren?

SELECT b.person_id, b.bestell_id, h.anzahl
from bestellungen as b

inner join person as s
ON (b.person_id = s.person_id)

SELECT b.person_id, s.name, s.vorname, b.bestell_id, b.bestelldatum,
from bestellungen as b

inner join person as s
ON (b.person_id = s.person_id)

INNER JOIN
(SELECT person_id, count(person_id) AS Anzahl
FROM bestellungen
where ( bedingung)
GROUP BY person_id
HAVING (COUNT(person_id) > 1) )
as h ON h.person_id = b.person_id
 
Werbung:
So aus der Hüfte über eine Abfrage schaffe ich es auch nicht ;)
Meine Idee wäre rekursiv, aber ja.. mysql ^^

Meine Lösungsmethode:
Eine "Hilfsansicht" erstellen, welche alle Bestellungen zählt und nach Personen gruppiert und aus dieser alles wählen, wo die gezählten Bestellungen über 1 sind.

Code:
create table personen(id int);
CREATE TABLE
create table bestellungen(id int primary key);
CREATE TABLE
create table personen(id int primary key);
CREATE TABLE
create table bestellt(bestellung int references bestellungen(id), person int references personen(id));
CREATE TABLE
insert into personen(id) select * from generate_series(1, 10);
INSERT 0 10
insert into bestellungen(id) select * from generate_series(1, 10);
INSERT 0 10
insert into bestellt(bestellung, person) values (1, 1);
INSERT 0 1
insert into bestellt(bestellung, person) values (2, 1);
INSERT 0 1
insert into bestellt(bestellung, person) values (1, 2);
INSERT 0 1
create view view_bestellungen as select count(bestellung), person from bestellt group by person;
CREATE VIEW
select * from view_bestellungen where count > 1;
 count | person
-------+--------
     2 |      1

Die Bestellung von Person 2, die nur einmal bestellt hat wird nichtmehr angezeigt ;)
 
Also Grundsätzlich bist du mit GROUP BY und HAVING count(*)>1 genau richtig. Das joinst du dann mit allen anderen Daten, wie in deinem letzten Beispiel. (Wobei ich nicht verstehe warum da am Ende zwei mal Select hintereinander steht, CopyPaste-Fehler?)

Das kann man jetzt auf verschiedene Weisen umstellen oder ein bisschen umformulieren aber das wird die Abfrage nicht wesentlich optimieren. Einzige echte Alternative zu diesem grundsätzlichen Vorgehen wäre nur das GROUP BY mit dem HAVING zu machen und bestell_id sowie b.bestelldatum zu aggregieren, z.B. müsste group_concat() gehen. Das hätte den Vorteil das du nur einmal die Tabelle bestellungen abfragst, ändert aber natürlich die Ausgabe sehr stark.

Was willst du denn mit der "Optimierung" erreichen? Grundsätzlich sollte das so nicht nur laufen sondern auch schnell sein.
 
Danke schön ukulele,
ja , ich hatte tatsächlich ein copy-paste-fehler.
Mein Ziel war es einfach, mich in mysql zu verbessern und bessere Lösungen kennenzulernen, falls möglich
 
Werbung:
Zurück
Oben