komplexe Abfrage

norbert_pdm

Aktiver Benutzer
Beiträge
25
Hallo, hallo alle,

ich steh gerade ziemlich auf'm Schlauch...
Ich habe den Teil einer Datenbank, den ich mit einem komplexerem Script abfragen will.
Der Teil der Datenbank, der relevant ist, sieht so aus:
upload_2021-2-2_22-36-53.png
Erstellt wird er mit:
Code:
CREATE TABLE tbl_gruppenzeit (
  tbl_gruppenzeit_ID INTEGER UNSIGNED  NOT NULL   AUTO_INCREMENT,
  tbl_gz_wochentag TEXT  NOT NULL  ,
  tbl_gz_start TIME  NULL  ,
  tbl_gz_laenge TIME  NOT NULL    ,
PRIMARY KEY(tbl_gruppenzeit_ID))
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

CREATE TABLE tbl_gruppe (
  tbl_gruppe_ID INTEGER UNSIGNED  NOT NULL   AUTO_INCREMENT,
  tbl_gruppe_name TEXT  NULL  ,
  tbl_gruppe_ort TEXT  NULL    ,
  tbl_gruppe_aktiv BIT(1)  NULL    ,
PRIMARY KEY(tbl_gruppe_ID))
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

CREATE TABLE tbl_mitarbeiter (
  tbl_mitarbeiter_ID INTEGER UNSIGNED  NOT NULL   AUTO_INCREMENT,
  tbl_ma_name TEXT  NULL  ,
  tbl_ma_vorname TEXT  NULL  ,
PRIMARY KEY(tbl_mitarbeiter_ID))
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

CREATE TABLE tbl_gruppe_has_tbl_gruppenzeit (
  tbl_gruppe_ID INTEGER UNSIGNED  NOT NULL  ,
  tbl_gruppenzeit_ID INTEGER UNSIGNED  NOT NULL    ,
PRIMARY KEY(tbl_gruppe_ID, tbl_gruppenzeit_ID)  ,
INDEX tbl_gruppe_has_tbl_gruppenzeit_FKIndex1(tbl_gruppe_ID)  ,
INDEX tbl_gruppe_has_tbl_gruppenzeit_FKIndex2(tbl_gruppenzeit_ID),
  FOREIGN KEY(tbl_gruppe_ID)
    REFERENCES tbl_gruppe(tbl_gruppe_ID)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION,
  FOREIGN KEY(tbl_gruppenzeit_ID)
    REFERENCES tbl_gruppenzeit(tbl_gruppenzeit_ID)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

CREATE INDEX IFK_Rel_16 ON tbl_gruppe_has_tbl_gruppenzeit (tbl_gruppe_ID);
CREATE INDEX IFK_Rel_17 ON tbl_gruppe_has_tbl_gruppenzeit (tbl_gruppenzeit_ID);

CREATE TABLE tbl_mitarbeiter_has_tbl_gruppe (
  tbl_mitarbeiter_ID INTEGER UNSIGNED  NOT NULL  ,
  tbl_gruppe_ID INTEGER UNSIGNED  NOT NULL    ,
PRIMARY KEY(tbl_mitarbeiter_ID, tbl_gruppe_ID)  ,
INDEX tbl_mitarbeiter_has_tbl_gruppe_FKIndex1(tbl_mitarbeiter_ID)  ,
INDEX tbl_mitarbeiter_has_tbl_gruppe_FKIndex2(tbl_gruppe_ID),
  FOREIGN KEY(tbl_mitarbeiter_ID)
    REFERENCES tbl_mitarbeiter(tbl_mitarbeiter_ID)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION,
  FOREIGN KEY(tbl_gruppe_ID)
    REFERENCES tbl_gruppe(tbl_gruppe_ID)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

CREATE INDEX IFK_rel_ma_magru ON tbl_mitarbeiter_has_tbl_gruppe (tbl_mitarbeiter_ID);
CREATE INDEX IFK_rel_magru_gru ON tbl_mitarbeiter_has_tbl_gruppe (tbl_gruppe_ID);

Wenn ich jetzt folgende Abfrage starte;
Code:
SELECT
                       gru.tbl_gruppe_name AS Name,
                       gru.tbl_gruppe_ort AS Ort,
                       GROUP_CONCAT(CONCAT(gz.tbl_gz_wochentag, ': ', gz.tbl_gz_start, ' - ', ADDTIME(tbl_gz_start, tbl_gz_laenge)) SEPARATOR ' | ') AS Zeit
                   FROM
                       tbl_gruppe_has_tbl_gruppenzeit gruzeit
                       LEFT JOIN tbl_gruppe gru ON gru.tbl_gruppe_ID = gruzeit.tbl_gruppe_ID
                       LEFT JOIN tbl_gruppenzeit gz ON gz.tbl_gruppenzeit_ID = gruzeit.tbl_gruppenzeit_ID
                   WHERE 
                       gru.tbl_gruppe_aktiv
                   GROUP BY
                       Nam

Erhalte ich eine 'vernünftige' Ausgabe....
ZB so was:
upload_2021-2-2_22-46-29.png
Wenn ich jetzt aber versuche, die Mitarbeiter der Gruppen entsprechend mit einzubinden:
Code:
SELECT
       gru.tbl_gruppe_name AS Name,
       gru.tbl_gruppe_ort AS Ort,
       GROUP_CONCAT(CONCAT(gz.tbl_gz_wochentag, ': ', gz.tbl_gz_start, ' - ', ADDTIME(tbl_gz_start, tbl_gz_laenge)) SEPARATOR ' | ') AS Zeit,
       GROUP_CONCAT(CONCAT(ma.tbl_ma_vorname, ' ', ma.tbl_ma_name) SEPARATOR ' | ' ) AS Mitarbeiter
FROM
       tbl_gruppe_has_tbl_gruppenzeit gruzeit
       LEFT JOIN tbl_gruppe gru ON gru.tbl_gruppe_ID = gruzeit.tbl_gruppe_ID
       LEFT JOIN tbl_gruppenzeit gz ON gz.tbl_gruppenzeit_ID = gruzeit.tbl_gruppenzeit_ID,
       tbl_mitarbeiter_has_tbl_gruppe madoku
       LEFT JOIN tbl_mitarbeiter ma ON ma.tbl_mitarbeiter_ID = madoku.tbl_mitarbeiter_ID
       LEFT JOIN tbl_gruppe gru2 ON gru2.tbl_gruppe_ID = madoku.tbl_gruppe_ID

WHERE 
       gru.tbl_gruppe_aktiv
GROUP BY
       Name
erhalte ich eine 'sinnlose' Ausgabe, in der sich die Mitarbeiter wiederholen...
upload_2021-2-2_22-50-9.png
Ich hatte erwartet, dass die Mitarbeiter pro Gruppe nur einmal auftauchen, aber das geschieht offensichtlich eben nicht...
Auch ein
Code:
GRPUP BY Name, Mitarbeiter
brachte nichts.
Woran kann das liegen?

Ich danke euch schon mal für eure Hilfe und das Hineindenken!
Norbert


upload_2021-2-2_22-36-53.png upload_2021-2-2_22-46-29.png upload_2021-2-2_22-50-9.png upload_2021-2-2_22-36-53.png upload_2021-2-2_22-46-29.png upload_2021-2-2_22-50-9.png
 
Werbung:
Du hast 4 Spalten im Result, davon 2 aggregiert. Und dann nur eine gruppiert. Das ist logisch falsch. Logisch wäre jetzt, daß MySQL Dir einen Fehler wirft - tut es nicht, weil zu blöd. Es liefert ein falsches Resultat - sehr blöd.

Wirf das (also MySQL) weg, es taugt nix, es ist Müll, es gibt besseres.
 
Das postgress besser ist, weiß ich mittlerweile auch ;-)

Wenn ich jetzt auch über Mitarbeiter gruppiere, schmießt es mir einen Fehler...
Erst mal SQL:
Code:
SELECT
       gru.tbl_gruppe_name AS Name,
       gru.tbl_gruppe_ort AS Ort,
       GROUP_CONCAT(CONCAT(gz.tbl_gz_wochentag, ': ', gz.tbl_gz_start, ' - ', ADDTIME(tbl_gz_start, tbl_gz_laenge)) SEPARATOR ' | ') AS Zeit,
       GROUP_CONCAT(CONCAT(ma.tbl_ma_vorname, ' ', ma.tbl_ma_name) SEPARATOR ' | ' ) AS Mitarbeiter
FROM
       tbl_gruppe_has_tbl_gruppenzeit gruzeit
       LEFT JOIN tbl_gruppe gru ON gru.tbl_gruppe_ID = gruzeit.tbl_gruppe_ID
       LEFT JOIN tbl_gruppenzeit gz ON gz.tbl_gruppenzeit_ID = gruzeit.tbl_gruppenzeit_ID,
       tbl_mitarbeiter_has_tbl_gruppe madoku
       LEFT JOIN tbl_mitarbeiter ma ON ma.tbl_mitarbeiter_ID = madoku.tbl_mitarbeiter_ID
       LEFT JOIN tbl_gruppe gru2 ON gru2.tbl_gruppe_ID = madoku.tbl_gruppe_ID

WHERE   
       gru.tbl_gruppe_aktiv
GROUP BY
       Name, Mitarbeiter

Und der Fehler:
MySQL meldet:

#1056 - Gruppierung über 'Mitarbeiter' nicht möglich


Ich befürchte viel eher, dass ich einen logischen Fehler mache...
 
Werbung:
Hallo akretschmer,

hast du einen Tipp für mich, an welcher Stelle, die innere Logik falsch ist?
VG, Norbert

Nun, stelle Dir einfach vor, Du erstellst eine Tabelle wie folgt:

Code:
test=# create table aggregation(spalte text, aggregiert bool not null, gruppiert bool not null, check ((case when aggregiert then 1 else 0 end) + (case when gruppiert then 1 else 0 end) = 1));
CREATE TABLE
test=*#

Du solltest dazu PostgreSQL nehmen, weil MySQL zwar die CHECK-Syntax wie dargestellt kennt, aber nicht beachtet. Dann füllst Du die 3 Spalten mit dem, was Du hast. Also, z.B., die erste Spalte in Deinem Ergebnis ist 'Name', das kommt in Spalte 1. Diese Spalte ist nicht aggregiert, also ein 'false' in die zweite Spalte. Du gruppierst danach, also ein 'true' in die dritte Spalte. Das machst Du mit allen Spalten in Deinem Result. Dabei wirst Du den Fehler dann merken (nochmals, mit MySQL wird das nicht funktionieren ...)
 
Zurück
Oben