1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Mysql doppelte Zeilen vermeiden

Dieses Thema im Forum "Relationale Datenbanksysteme" wurde erstellt von Sprint, 11. April 2018.

  1. Sprint

    Sprint Erfahrenes Mitglied

    Hallo zusammen,

    erst einmal sorry für die blöde Überschrift. Mir ist nichts besseres eingefallen.

    Zu meinem Problem. Ich habe hier zwei Tabellen, die eine beinhaltet verschiedene Schulungen, die andere die entsprechenden Teilnehmer:

    Schulungen: kursid, typ, start
    Teilnehmer: tid, kursid, anzahl, storniert

    Für einen Buchungskalender werden die Kurse so abgefragt:

    select distinct s.*, t.anzahl
    from schulungen s
    left join teilnehmer t on s.kursid = t.kursid and t.storniert = '0000-00-00 00:00:00'
    where s.start between '$suchstart' and '$suchende'

    Das funktioniert, solange ich keine oder nur eine Anmeldung für einen Termin habe. Wenn aber mehrere Anmeldungen für einen Kurs vorliegen, wird dieser Kurs entsprechend mehrfach ausgegeben. Das stört aber die anschließende Kalendererstellung.

    So kann das z.B. aussehen:

    kursidtypstartanzahl
    262018-05-07NULL
    712018-06-185
    822018-06-202
    822018-06-201
    1142018-07-02NULL
    ----
    822018-06-203
    Wie man sieht, ist der Kurs mit der id 8 zwei Mal gebucht und wird entsprechend zwei Mal ausgegeben. Ich bräuchte aber eine Ausgabe wie in der letzten Zeile dargestellt, also nur eine Zeile mit addierter Anzahl.

    Ist das irgendwie machbar oder muß ich das über php lösen?
    Danke schon mal im Voraus,
    Sprint
     
  2. Biber3

    Biber3 Erfahrenes Mitglied

    Moin Sprint,

    versuch es so:
    Code (SQL):
    1. SELECT s.kurstyp, s.typ, s.START , t.anzahl
    2. FROM schulungen s
    3. LEFT JOIN (SELECT kursid, SUM(t.anzahl) AS Anzahl
    4.     FROM teilnehmer
    5.     WHERE storniert = '0000-00-00 00:00:00' )
    6. t ON s.kursid = t.kursid
    7. WHERE s.START BETWEEN '$suchstart' AND '$suchende'
    8. ;
    Grüße
    Biber
     
  3. Sprint

    Sprint Erfahrenes Mitglied

    Hallo Biber,

    kann es sein, daß da was durcheinander gekommen ist? Egal was ich probiere bzw. ändere, ich bekomme in phpMyAdmin immer die Meldung "Für jede abgeleitete Tabelle muss ein eigener Alias angegeben werden".
     
  4. Biber3

    Biber3 Erfahrenes Mitglied

    Moin Sprint,

    sorry, mein Fehler.

    Code (SQL):
    1. SELECT s.kurstyp, s.typ, s.START , t.anzahl
    2. FROM schulungen s
    3. LEFT JOIN (SELECT kursid, SUM(anzahl) AS Anzahl
    4.     FROM teilnehmer
    5.     WHERE storniert = '0000-00-00 00:00:00' )
    6. t ON s.kursid = t.kursid
    7. WHERE s.START BETWEEN '$suchstart' AND '$suchende'
    8. ;
    ( es musste sum(anzahl) statt sum(t.anzahl) lauten)

    Grüße
    Biber
     
  5. bofh1337

    bofh1337 Erfahrenes Mitglied

    Wenn "kursid" ein Index , kannst du auch "using kursid" nehmen
     
  6. Sprint

    Sprint Erfahrenes Mitglied

    Hallo Biber,

    jetzt funktioniert es zwar, allerdings werden jetzt ALLE Teilnehmer aus allen vorhandenen Kursen zusammengezählt und bei einem Eintrag ausgegeben. Wahrscheinlich habe ich mich da verkehrt ausgedrückt. Um bei der obigen Tabelle zu bleiben, müßte das korrekte Ergebnis so aussehen:


    kursidtypstartanzahl
    262018-05-07NULL
    712018-06-185
    822018-06-203
    1142018-07-02NULL
    Es soll also zu jedem einzelnen Kurs die Gesamtanzahl der jeweiligen Teilnehmer ausgegeben werden. Wie eben bei Kurs 8, für den zwei Buchungen mit 1 bzw. 2 Teilnehmern vorliegen, zusammen also 3.
     
  7. Sprint

    Sprint Erfahrenes Mitglied

    Ich habe es jetzt selbst geschafft, eine vermutliche Lösung hinzukriegen:

    select s.*,
    (select sum(t.anzahl) from teilnehmer t where t.kursid = s.kursid) as anzahl
    from schulungen s
    left join teilnehmer t on s.kursid = t.kursid and t.storniert = '0000-00-00 00:00:00'
    where s.start between '$suchstart' and '$suchende'
    group by s.kursid

    Zumindest bekomme ich jetzt die richtigen Ergebnisse. Ob sich da noch ein Fehler drin versteckt hat, wird sich erst über die Zeit zeigen.
     
  8. Biber3

    Biber3 Erfahrenes Mitglied

    Moin Sprint,

    sorry noch mal. Hab gestern wohl etwas unkonzentriert gepostet - in meiner Variante fehlte auch die entscheidende GROUP BY-Zeile.
    Code (SQL):
    1. SELECT s.kurstyp, s.typ, s.START , t.anzahl
    2. FROM schulungen s
    3. LEFT JOIN (SELECT kursid, SUM(anzahl) AS Anzahl
    4.     FROM teilnehmer
    5.     WHERE storniert = '0000-00-00 00:00:00'
    6.     GROUP BY kursid
    7. )
    8. t ON s.kursid = t.kursid
    9. WHERE s.START BETWEEN '$suchstart' AND '$suchende'
    10. ;
    Andererseits.... wenn du durch durch meine Schlamperei eine eigene Lösung suchen musstest und gefunden hast, hilft dir das eventuell mehr.

    Grüße
    Biber
     
Die Seite wird geladen...