Select über mehrere Tabellen aber Ausgabe teilweise nur einfach

compoundbow83

Neuer Benutzer
Beiträge
3
Hallo Zusammen,
ich bin gerade Datei eine Termindatenbank mit Einbuchungsoption zu realisieren.

Nun muss ich Daten aus drei Tabellen auslesen (das bekomme ich hin). Aber ich möchte bei der Ausgabe Daten aus der einen Tabelle nur einmal ausgaben.

Mein Code sieht aktuell so aus:
PHP:
$abfrage = "SELECT * from yoga_termine, yoga_teilnehmer, yoga_user WHERE yoga_teilnehmer.id_user = yoga_user._id AND yoga_teilnehmer.id_termin = yoga_termine.id AND yoga_termine.datum >= curdate() ORDER BY yoga_termine.datum ASC, yoga_user._name ASC";


$result = mysqli_query($connect_id,$abfrage);
while ($row = mysqli_fetch_array ($result))
{

    $id=$row['id'];
    $id_user=$row['id_user'];
    $_name=$row['_name'];
    $date = strtotime($row[datum]);
    $datum = date("d.m.Y",$date);

echo"
$datum
$_name

Mit diesem Code sieht die Ausgabe aber so aus:
12.04.2022 Name 1
30.04.2022 Name 1
30.04.2022 Name 2

Wie bekomme ich es denn hin, dass die Ausgabe so aussieht:

12.04.2022
Name 1

30.04.2022
Name 1
Name 2

Bedeutet, ich will das Datum egal wieviele Teilnehmer an dem Termin vorhanden sind nur einmal über den Teilnehmern ausgeben.

Ich habe leider aktuell keinen wirklichen Ansatz wie ich das hinbekomme.

Es würde mich sehr freuen, wenn ihr mir hier Tipps geben könntet.

Manuel
 
Werbung:
der Ansatz nennt sich Aggregation. Du gruppierst nach dem Datum und listest alle Namen dazu auf.

Die Ausgabeformatierung ist Aufgabe von PHP und hier Offtopic.
 
Hier mal der SQL-Teil für den Einstieg:
SQL:
SELECT yoga_termine.datum,yoga_user._name
FROM yoga_termine
INNER JOIN yoga_teilnehmer
ON yoga_teilnehmer.id_termin = yoga_termine.id
INNER JOIN yoga_user
ON yoga_teilnehmer.id_user = yoga_user._id
WHERE yoga_termine.datum >= curdate()
GROUP BY yoga_termine.datum,yoga_user._name
ORDER BY yoga_termine.datum ASC, yoga_user._name ASC
a) Durch GROUP BY wird gruppiert. In deinem Fall wird nicht aggregiert aber das geht natürlich auch, z.B. könnte ein count(*) noch die Anzahl liefern.
b) SELECT * bitte nur zum testen verwenden, in fertigem Code immer explizite Spalten benennen.
c) Ebenfalls explizit joinen, alles andere ist schlechter Stil und führt schneller zu Denkfehlern.
 
a) Durch GROUP BY wird gruppiert.
Das wäre gemäß Ausgangsstatement und angenommen korrekter Modellierung gar nicht nötig oder?
Mit diesem Code sieht die Ausgabe aber so aus:
12.04.2022 Name 1
30.04.2022 Name 1
30.04.2022 Name 2

Wie bekomme ich es denn hin, dass die Ausgabe so aussieht:

12.04.2022
Name 1

30.04.2022
Name 1
Name 2
Genau diese Ausgabe wäre z.B. mit einem Union Statement zu erreichen oder auch Rollup oder auch Window Functions. Das Statement wird dann relativ komplex in Vergleich zum jetzigen. Man würde das vermutlich eher in der Ausgabe in PHP realisieren.
 
#2 habe ich so verstanden, dass Du ein String Aggregat der Namen je Datum bauen willst. Das wäre natürlich in PHP zu verarbeiten, aber entspricht nicht der dargestellten Ausgabe im Eröffnungspost. Oder habe ich das falsch verstanden?
 
Code:
postgres=# create table bla(datum date, person text);
CREATE TABLE
postgres=# insert into bla values ('2022-04-12','Name 1');
INSERT 0 1
postgres=# insert into bla values ('2022-04-30','Name 1');
INSERT 0 1
postgres=# insert into bla values ('2022-04-30','Name 2');
INSERT 0 1
postgres=# select datum, array_agg(person) from bla group by datum;
   datum    |      array_agg      
------------+---------------------
 2022-04-30 | {"Name 1","Name 2"}
 2022-04-12 | {"Name 1"}
(2 rows)

postgres=#

Das kannst Du dann in PHP zeilenweise einlesen und zu

Code:
12.04.2022
   Name 1
30.04.2022
   Name 1
   Name 2

wandeln.
 
Sorry für die verspätete Antwort, aber wenn ich jetzt nicht total falsch bin, war unter diesem Thema gleich als zweiter Post eine Info, dass ich hier falsch bin, weil es sich um php handelt.

Die ich das hier jetzt heute erst lese, habe ich jetzt schon eine Lösung gefunden mit diesem Code:
PHP:
<?php
include("config.inc.php");
include("datenbank.inc.php");
$connect_id = mysqli_connect($host, $user, $pass) or die ("Keine Verbindung zu der Datenbank m�glich.");
mysqli_select_db($connect_id, $db);

$abfrage = "SELECT yoga_user._name, yoga_termine.datum from yoga_termine
              INNER JOIN yoga_teilnehmer ON yoga_teilnehmer.id_termin = yoga_termine.id
              INNER JOIN yoga_user ON yoga_user._id = yoga_teilnehmer.id_user
              WHERE yoga_teilnehmer.id_user = yoga_user._id AND yoga_teilnehmer.id_termin = yoga_termine.id AND yoga_termine.datum >= curdate() ORDER BY yoga_termine.datum ASC, yoga_user._name ASC";

$result = mysqli_query($connect_id,$abfrage);
$last_entry = null;
while ($row = mysqli_fetch_array ($result))
{

    $id=$row['id'];
    $id_user=$row['id_user'];
    $_name=$row['_name'];
    $date = strtotime($row[datum]);
    $datum = date("d.m.Y",$date);

    $tag1 = date("w", $date);
    $tagnamen1 = array("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag");
    $tagname1 = $tagnamen1[$tag1];

   if ($last_entry != $datum) {
        echo'<hr class="myhrline" width="200px" align="left" style="border: 0; height: 5px; background-image: linear-gradient(to right, #3B3B3B, #008D71, #3B3B3B);" />';
        echo" <h3 style='margin-bottom:0px'>$datum ($tagname1)<br></h3>";
        $last_entry = $datum;
    }
    echo" <li> $_name</li>";

}

echo'<hr class="myhrline" width="200px" align="left" style="border: 0; height: 5px; background-image: linear-gradient(to right, #3B3B3B, #008D71, #3B3B3B);" />';

mysqli_close($connect_id);
?>
 
Werbung:
Ich habe leider aktuell keinen wirklichen Ansatz wie ich das hinbekomme.

Auch wenn's zu spät ist, das wäre ein möglicher Weg, das gewünschte Ergebnis direkt aus SQL zu erhalten. (Hab das optimierte Statement von @ukulele weiterverwendet)

Code:
SELECT 
       case when _name is null then datum else _name end
       as Ergebnis1Spalte
  FROM yoga_termine 
 INNER JOIN yoga_teilnehmer
       ON yoga_teilnehmer.id_termin = yoga_termine.id
 INNER JOIN yoga_user
       ON yoga_teilnehmer.id_user = yoga_user._id
 group by datum, _name  with rollup 
having (datum is not null or _name is not null)
 order by datum, _name

Nebenbei mal wieder eine Gelegenheit, wo Group By sich nicht an den ausgegebenen Spalten orientiert.
 
Zurück
Oben