Abfrage mehrerer Tabellen mit unbekannter Anzahl in einer Tabelle

Kurt_S

Benutzer
Beiträge
5
Hallo zusammen

Ich bin noch ein ziemlicher Anfänger in SQL und versuche meine Abfragen möglichst mit Hilfe von Bücher und Artikeln im Internet zusammen zu stellen, einfach um das gleich gesagt zu haben.
Jetzt stehe ich jedoch vor einem Problem, bei dem ich nicht einmal weiss, nach was ich suchen soll. Daher auch der etwas seltsame Titel...


Ich habe vier Tabellen, category, edition, edition_series und typ. Diese sind wie folgt aufgebaut.

Code:
edition            edition_series          typ
---------          ------------------        ------------
id                  id                             id
name            edition_id                  edition_id
cat_id           serie_nr                     serie_id
...                 ...                      image_name
                                             ...

Nun brauche ich die edition anhand der cat_id, die anzahl der Serien in einer edition und die Bilder aus der Tabelle Typ, die zu der edition gehören. Dies betrifft meist mehrere editionen, sodass nicht alle edition gleich viele Bilder aus typ zugewiesen werden.

Bisher bin ich soweit, dass mir alles ausgegeben wird, ausser den Bildern.
Code:
SELECT e.id, e.name, e.editiondate, e.earlydate, e.rateduration, COUNT(es.serie_nr) FROM edition AS e
LEFT JOIN edition_series AS es ON es.edition_id = e.id
WHERE e.cat_id = '1'
GROUP BY e.id

Ich weiss einfach nicht, wie ich jetzt die Bilder zusätzlich noch holen soll, sodass diese beispielsweise alle in einem Feld aufgezählt werden. Natürlich könnte ich danach in python jedes Tuple durchgehen und eine weitere Abfrage starten, möchte die aber wenn möglich vermeiden.

Hoffe ich hab mich einigermassen verständlich ausgedrückt.
Für Hilfe und Anregungen wäre ich sehr dankbar.

Besten Grüsse
Kurt
 
Werbung:
Du kannst die aggregieren, in PostgreSQL via array_agg() oder string_agg(), allerdings ist Deine Abfrage logisch falsch, Du aggregierst nach einer Spalte und hast 5 Spalten im Select-Teil, wovon aber nur eine im GROUP BY steht. Alle Datenbanken dieser Welt würden hier einen syntaxfehler sehen, und auch MySQL in seiner aktuellsten Mutation.
 
Ähm, falls e.id als PRIMARY KEY definiert ist, würde das so in Ordnung gehen mit Deinem Select. Dann wäre das ein hinreichendes bzw. ausreichendes Kriterium für das GROUP BY. Das kann ich aber nicht erkennen, ob das der Fall ist.

Code:
test=# create table edition(id int primary key, name text, cat_id int, editiondate date, earlydate date);
CREATE TABLE
test=*# create table edition_series(id int primary key, edition_id int references edition, serie_nr int);
CREATE TABLE
test=*# create table typ(id int primary key, edition_id int references edition, serie_id int references edition_series, image_name text);
CREATE TABLE

test=*# select e.id, e.name, e.editiondate, e.earlydate, count(es.serie_nr), string_agg(t.image_name,',') from edition e left join edition_series es on e.id=es.edition_id left join typ t on t.edition_id=e.id where e.cat_id = 1 group by e.id;
 id | name | editiondate | earlydate | count | string_agg
----+------+-------------+-----------+-------+------------
(0 Zeilen)

Aber:

Code:
test=*# create table edition2(id int, name text, cat_id int, editiondate date, earlydate date);
CREATE TABLE
test=*# select e.id, e.name, e.editiondate, e.earlydate, count(es.serie_nr), string_agg(t.image_name,',') from edition2 e left join edition_series es on e.id=es.edition_id left join typ t on t.edition_id=e.id where e.cat_id = 1 group by e.id;
FEHLER:  Spalte »e.name« muss in der GROUP-BY-Klausel erscheinen oder in einer Aggregatfunktion verwendet werden
ZEILE 1: select e.id, e.name, e.editiondate, e.earlydate, count(es.se...
 
Du hast recht, das hatte ich nicht geschrieben. e.id ist ein Primary Key, desshalb hats wohl auch funktioniert. Hab das mal getestet mit einem Feld das kein Primary Key ist, dann funktionierts auch nicht. Ist gut zu wissen, sonst wär ich sonst mal darüber gestolpert.

Jetzt sieht das ganze so aus, GROUP_CONCAT ist, so wie ich das verstehe, das äquivalent zu array_agg(). Wusste dank dir nach was ich suchen muss :)
Code:
SELECT e.id, e.name, e.editiondate, e.earlydate, COUNT(es.serie_nr), GROUP_CONCAT(t.image_name) FROM edition e
LEFT JOIN edition_series es ON e.id=es.edition_id
LEFT JOIN typ t ON t.edition_id=e.id
WHERE e.cat_id = 1
GROUP BY  e.id

Jetzt hab ich dafür das Problem, dass der Count auf die Serien_Nr. nicht mehr richtig funktioniert bzw. nicht so wie ich es gerne hätte.
Ich habe z.B. zwei Serien und 4 Bilder, da gibt der Cound 8 aus. Bei einer Serie und 6 Bildern gibt er 6 aus. Als würde er alle Bildfelder durchlaufen und hochzählen.

Das Problem hat sicher damit zu tun, dass ich noch zu wenig verstehe wie das genau funktioniert.

Besten Dank für deine bisherigen Tips, hast mich einen riesigen Schritt vorwärts gebracht...
 
Code:
test=*# select * from edition;
 id | name  | cat_id | editiondate | earlydate  
----+-------+--------+-------------+------------
  1 | edi 1 |  1 | 2016-12-09  | 2016-12-09
  2 | edi 2 |  1 | 2016-12-09  | 2016-12-09
  3 | edi 3 |  2 | 2016-12-09  | 2016-12-09
(3 Zeilen)

test=*# select * from edition_series ;
 id | edition_id | serie_nr
----+------------+----------
  1 |  1 |  1
  2 |  1 |  2
  3 |  2 |  3
  4 |  2 |  1
  5 |  2 |  2
(5 Zeilen)

test=*# select * from typ ;
 id | edition_id | serie_id | image_name
----+------------+----------+------------
  1 |  1 |  1 | bild 1
  2 |  1 |  2 | bild 2
  3 |  2 |  1 | bild 21
  4 |  2 |  2 | bild 22
(4 Zeilen)

test=*# select e.id, e.name, e.editiondate, e.earlydate, count(distinct es.serie_nr), string_agg(distinct t.image_name,',') from edition e left join edition_series es on e.id=es.edition_id left join typ t on t.edition_id=e.id where e.cat_id = 1 group by e.id,es.edition_id;
 id | name  | editiondate | earlydate  | count |  string_agg   
----+-------+-------------+------------+-------+-----------------
  1 | edi 1 | 2016-12-09  | 2016-12-09 |  2 | bild 1,bild 2
  2 | edi 2 | 2016-12-09  | 2016-12-09 |  3 | bild 21,bild 22
(2 Zeilen)

test=*#

Hilft das?
 
es kann übrigens recht schnell passieren, daß Dir meine Tipps nicht weiterhelfen, weil ich PostgreSQL nutze, was deutlich mehr Features als MySQL hat.
 
Werbung:
Das habe ich beim suchen und lesen jetzt auch gesehen. Aber diesesmal hast mir sehr geholfen. Meist findet man trotzdem einen Weg, sobald man mal weiss wonach man suchen muss.
Ev. wird das ganze ja mal auf PostgreSQL portiert, war schon einmal angedacht.
 
Zurück
Oben