fabian: MYSQL Abfrage bei doppelt. While Schleife sortieren lassen: WIE?

Hallo liebe Forum-Gemeinde,

ich rätsele hier an einem Problem, welches ich einfach nicht lösen kann.

Ich möchte Daten abfragen und sortieren lassen, wobei insgesamt drei Tabellen beteiligt sind.

Da ich mit den dreifach joins nicht so recht klarkomme, habe ich eine Abfrage erstellt, mit deren Ergebnisse die neue Abfrage durchgeführt wird. Nun möchte ich jedoch die Ergebnisse der zweiten Abfrage sortieren lassen.

Hier ist der relevante Bereich:

$result_stellenanzeigen_neu = mysql_query("SELECT stellen_id, zeit_anfang FROM stellenanzeigen WHERE TO_DAYS(zeit_ende) >= TO_DAYS(NOW()) AND status ='4'");
while ($row = mysql_fetch_array($result_stellenanzeigen_neu))
{
$stellen_id=$row["stellen_id"];
$zeit_anfang=$row["zeit_anfang"];

$result_stellenanzeigen_neu_2 = mysql_query("SELECT krit_suche.stellenbez, krit_suche.bereich, krit_suche.firma, krit_suche.ort, krit_suche.plz FROM krit_suche INNER JOIN krit_suche_id_stellen_id ON (krit_suche.krit_suche_id = krit_suche_id_stellen_id.krit_suche_id) WHERE krit_suche_id_stellen_id.stellen_id = '$stellen_id' ORDER BY $sortierung");
while ($row = mysql_fetch_array($result_stellenanzeigen_neu_2))
{
$stellenbez=$row["stellenbez"];
$bereich=$row["bereich"];
$firma=$row["firma"];
$ort=$row["ort"];
$plz=$row["plz"];
...

Das Problem wird sein, dass die erste While Schleife nur jeweils ein Wert durchgibt, auf dessen die zweite Abfrage wiederum nur einen Wert liefert, der dann natürlich nicht soriert werden kann.

Geht das ganze mit PHP zu sortieren oder komme ich um den Join Salat nicht herum?

Vielen Vielen Dank, schon jetzt für alle Antworten

Grüße Fabian aus Braunschweig

  1. Hallo liebe Forum-Gemeinde,

    ich rätsele hier an einem Problem, welches ich einfach nicht lösen kann.

    Ich möchte Daten abfragen und sortieren lassen, wobei insgesamt drei Tabellen beteiligt sind.

    Da ich mit den dreifach joins nicht so recht klarkomme, habe ich eine Abfrage erstellt, mit deren Ergebnisse die neue Abfrage durchgeführt wird. Nun möchte ich jedoch die Ergebnisse der zweiten Abfrage sortieren lassen.

    Hier ist der relevante Bereich:

    $result_stellenanzeigen_neu = mysql_query("SELECT stellen_id, zeit_anfang FROM stellenanzeigen WHERE TO_DAYS(zeit_ende) >= TO_DAYS(NOW()) AND status ='4'");
    while ($row = mysql_fetch_array($result_stellenanzeigen_neu))
    {
    $stellen_id=$row["stellen_id"];
    $zeit_anfang=$row["zeit_anfang"];

    $result_stellenanzeigen_neu_2 = mysql_query("SELECT krit_suche.stellenbez, krit_suche.bereich, krit_suche.firma, krit_suche.ort, krit_suche.plz FROM krit_suche INNER JOIN krit_suche_id_stellen_id ON (krit_suche.krit_suche_id = krit_suche_id_stellen_id.krit_suche_id) WHERE krit_suche_id_stellen_id.stellen_id = '$stellen_id' ORDER BY $sortierung");
    while ($row = mysql_fetch_array($result_stellenanzeigen_neu_2))
    {
    $stellenbez=$row["stellenbez"];
    $bereich=$row["bereich"];
    $firma=$row["firma"];
    $ort=$row["ort"];
    $plz=$row["plz"];
    ...

    Das Problem wird sein, dass die erste While Schleife nur jeweils ein Wert durchgibt, auf dessen die zweite Abfrage wiederum nur einen Wert liefert, der dann natürlich nicht soriert werden kann.

    Geht das ganze mit PHP zu sortieren oder komme ich um den Join Salat nicht herum?

    Vielen Vielen Dank, schon jetzt für alle Antworten

    Grüße Fabian aus Braunschweig

    Hi,

    hab' von PHP keine Ahnung meine aber zu erkennen, dass Du das Problem SQL-seitig lösen solltest. Joins sind zwar etwas gewöhnungsbedürftig, aber nicht wirklich strange.

    btw - Du kannst die Joins auch in der WHERE-Klausel definieren:

    select
     *
    from
     tableA
    where
     (tableA.Datenfeld1=tableB.Datenfeld2) and
     (tableB.Datenfeld2=tabelC.Datenfeld3) -- usw. (Datenfeldtyp der Datenfelder muss übereinstimmen)

    • Also ein Join ohne Join-Klausel. Vielleicht gefällts.

    Gruss,
    Lude

    1. Hallo Lude,

      vielen Dank für deine Mithilfe.

      Das man solche Abfragen auch machen kann, wußte ich noch nicht. Es sieht auch relativ einfach aus.
      Mit den Joins komme ich nicht so zurecht, so dass ich deine Lösung in Zukunft wohl des öfteren anwenden werde.

      Danke nochmal und Grüße aus Braunschweig

      Fabian

  2. Hi

    $result_stellenanzeigen_neu_2 = mysql_query("SELECT krit_suche.stellenbez, krit_suche.bereich, krit_suche.firma, krit_suche.ort, krit_suche.plz FROM krit_suche INNER JOIN krit_suche_id_stellen_id ON (krit_suche.krit_suche_id = krit_suche_id_stellen_id.krit_suche_id) WHERE krit_suche_id_stellen_id.stellen_id = '$stellen_id' ORDER BY $sortierung");

    da kannst du dir das JOIN auch sparen, da du nur genau einen Wert ($stellen_id) rausfilterst und von krit_suche_id_stellen_id keine Spalten haben willst.

    ohne genauere Kenntnis der DB-Struktur müsste aber folgendes funktionieren :

    "SELECT ks.stellenbez, ks.bereich, ks.firma, ks.ort, ks.plz FROM krit_suche AS ks LEFT JOIN stellenanzeigen as st ON st.stellen_id=ks.krit_suche_id  WHERE TO_DAYS(st.zeit_ende) >= TO_DAYS(NOW()) AND st.status ='4' ORDER BY st.zeit_anfang"

    Mit "AS" definierst du einen Alias für die Tabellennamen. Damit wird das Statement kürzer.

    1. Hallo Vimes,

      vielen Dank für deine schnelle Antwort. Das Benutzen der Aliase werde ich mir angewöhnen, es schafft wirklich eine viel bessere ÜBersicht.

      Dein Statement habe ich soweit übernommen, danke. Es funktioniert auch, wobei das Sortieren an sich, jedoch noch immer nicht geht.

      //aktuelle online stellenanzeigen anzeigen
      $result_stellenanzeigen_neu = mysql_query("SELECT stellen_id, zeit_anfang FROM stellenanzeigen WHERE TO_DAYS(zeit_ende) >= TO_DAYS(NOW()) AND status ='4'");
      while ($row = mysql_fetch_array($result_stellenanzeigen_neu))
      {
      $stellen_id=$row["stellen_id"];
      $zeit_anfang=$row["zeit_anfang"];

      $result_stellenanzeigen_neu_2 = mysql_query("SELECT ks.stellenbez, ks.bereich, ks.firma, ks.ort, ks.plz FROM krit_suche AS ks LEFT JOIN stellenanzeigen as st ON st.stellen_id=ks.krit_suche_id  WHERE TO_DAYS(st.zeit_ende) >= TO_DAYS(NOW()) AND st.status ='4' ORDER BY $sortierung");
      while ($row = mysql_fetch_array($result_stellenanzeigen_neu_2))
      {
      $stellenbez=$row["stellenbez"];
      $bereich=$row["bereich"];
      $firma=$row["firma"];
      $ort=$row["ort"];
      $plz=$row["plz"];

      Hier habe ich dein Statement ergänzt um die Abfrage stellen_id die ich auch benötige und den ersten Teil weggelassen. Das Ergebnis läßt sich nun zwar sortieren, aber als Ergebnis selbst erhalte ich das Quadrat der normalen Ausgabe. D.h. jedes Ergebnis wird sooft wiederholt, wie unterschiedliche Ergebnisse insgesamt vorhanden sind. Die Variable Sortierung erhält nur die einzelnen Spaltenüberschriften z.b (bereich desc)

      $result_stellenanzeigen_neu_2 = mysql_query("SELECT stellenanzeigen.stellen_id, ks.stellenbez, ks.bereich, ks.firma, ks.ort, ks.plz FROM stellenanzeigen, krit_suche AS ks LEFT JOIN stellenanzeigen as st ON st.stellen_id=ks.krit_suche_id  ORDER BY $sortierung");
      while ($row = mysql_fetch_array($result_stellenanzeigen_neu_2))
      {
      $stellenbez=$row["stellenbez"];
      $bereich=$row["bereich"];
      $firma=$row["firma"];
      $ort=$row["ort"];
      $plz=$row["plz"];

      Vielleicht gibt es ja hier irgendwo einen Zwischenweg?

      Danke nochmal und Grüße aus Braunschweig

      Fabian

      1. Hallo fabian,

        vielen Dank für deine schnelle Antwort. Das Benutzen der Aliase werde ich mir angewöhnen, es schafft wirklich eine viel bessere ÜBersicht.

        Dein Statement habe ich soweit übernommen, danke. Es funktioniert auch, wobei das Sortieren an sich, jedoch noch immer nicht geht.

        Hier habe ich dein Statement ergänzt um die Abfrage stellen_id die ich auch benötige und den ersten Teil weggelassen. Das Ergebnis läßt sich nun zwar sortieren, aber als Ergebnis selbst erhalte ich das Quadrat der normalen Ausgabe. D.h. jedes Ergebnis wird sooft wiederholt, wie unterschiedliche Ergebnisse insgesamt vorhanden sind.

        Klar, da du Stellenanzeigen 2x joinst, einmal mit Inner (durch das stellenanzeigen,krit_suche) und dann mit Left.

        Also nur

        $result_stellenanzeigen_neu_2 = mysql_query("SELECT st.stellen_id, ks.stellenbez, ks.bereich, ks.firma, ks.ort, ks.plz FROM  krit_suche AS ks LEFT JOIN stellenanzeigen as st ON st.stellen_id=ks.krit_suche_id  ORDER BY $sortierung");

        --oder--

        Du kannst für st.stellen_id auch gleich ks.krit_suche_id verwenden wg des Joins.

        $result_stellenanzeigen_neu_2 = mysql_query("SELECT ks.krit_suche_id, ks.stellenbez, ks.bereich, ks.firma, ks.ort, ks.plz FROM  krit_suche AS ks LEFT JOIN stellenanzeigen as st ON st.stellen_id=ks.krit_suche_id  ORDER BY $sortierung");

        Ynwa.

        1. Hallo Ynwa,

          vielen Dank nochmal für deine Hilfe.

          Ich habe die Abfrage übernommen, jedoch wird ein falscher Wert angezeigt. Es wird nur eine stellen ID angezeigt, zu der es gerade keine Krit_Suche_id gibt.
          Das LEFT join gibt so weit ich weiss Werte zurück, die zwar in der einen, aber nicht in der anderen Tabelle vorzufinden sind. Ich glaube diese Verwendung ist hier verkehrt.

          Wahrscheinlich ist es nur ein ganz kleiner Gedankenfehler, weil ich die Strucktur der DB noch nicht dargestellt habe.

          Ohne diese Abfrage komme ich jedoch nicht weiter, so dass ich es noch einmal hier versuche. Vielleicht hast du ja nochmal Lust, mir einen Tipp zu geben?

          Das Prinzip geht folgender Maßen:

          Wenn eine Anzeige erstellt wird, wird sofort die Tabelle Stellenanzeigen aktualisiert und eine Id verteilt.

          Sobald der user auch die Kriterien festlegt, wird die Tabelle krit_suche erweitert und ebenfalls eine neue ID vergeben.

          Die Tabelle krit_suche_id_stellen_id bringt die beiden ID´s zusammen.

          Anhand der Stellen id, wird die Stellenanzeige gefunden und angezeigt. Die Zeitfunktion zeit_ende und der status geben in der Tabelle Stellenanzeigen an, ob die Stellenanzeige für die Öffentlichkeit angezeigt werden darf.

          Die Stellenbezeichnung, Ort, PLZ.. für die Übersicht sind in der Tabelle krit_suche hinterlegt.

          Nun müßte ich zuerst die Tabelle Stellenanzeigen abfragen und alle Daten auslesen, die dem Status "öffentlich" entsprechen.

          Wenn ich diese habe, ziehe ich mir mit Hilfe der Tabelle krit_suche_id_stellen_id die richtige krit_id heraus und lese in dieser die jeweilige Zeile aus. Nach dieser Zeile möchte ich die Stellenanzeigen-Ergebnisse dann auch sortieren.

          Die absolute Krönug wäre es noch, wenn ich auch die Option anbieten könnte auch noch nach der Spalte zeit_ende in der Tabelle Stellenanzeigen zu sortieren.

          Hier noch einmal der letzte Stand der Dinge:

          $result_stellenanzeigen_neu_2 = mysql_query("SELECT ks.krit_suche_id, ks.stellenbez, ks.bereich, ks.firma, ks.ort, ks.plz FROM  krit_suche AS ks LEFT JOIN stellenanzeigen as st ON st.stellen_id=ks.krit_suche_id  ORDER BY $sortierung");

          Danke, danke, danke

          Grüße aus Braunschweig

          Fabian

          1. Hallo Fabian

            Ich habe die Abfrage übernommen, jedoch wird ein falscher Wert angezeigt. Es wird nur eine stellen ID angezeigt, zu der es gerade keine Krit_Suche_id gibt.
            Das LEFT join gibt so weit ich weiss Werte zurück, die zwar in der einen, aber nicht in der anderen Tabelle vorzufinden sind. Ich glaube diese Verwendung ist hier verkehrt.

            Das stimmt nicht. a LEFT JOIN b ON .. findet ALLE Datensätze aus a und nur die Datensätze aus b mit entsprechendem Datensatz in a.

            Bei deiner DB-Struktur ist das allerdings egal, da es zu jedem Datensatz aus krit_suche wohl einen in krit_suche_id_stellen_id gibt
            und dafür auch garantiert einen in stellenanzeigen, wenn ich die Reihenfolge richtig verstanden hab.

            Die Tabelle krit_suche_id_stellen_id bringt die beiden ID´s zusammen.

            OK - das ist das entscheidende Detail, was mir? fehlte.

            Nun müßte ich zuerst die Tabelle Stellenanzeigen abfragen und alle Daten auslesen, die dem Status "öffentlich" entsprechen.

            Das geht auch bei der JOIN-Abfrage mit WHERE

            Die absolute Krönug wäre es noch, wenn ich auch die Option anbieten könnte auch noch nach der Spalte zeit_ende in der Tabelle Stellenanzeigen zu sortieren.

            Option? Im Sinne von Auswahl - das geht imho nicht in SQL.
            Sonst ORDER BY geht mit (fast-kein BLOB etc) allen Spalten, die selektiert werden,

            ALSO 3-fach JOIN

            $result_stellenanzeigen_neu_2 = mysql_query("SELECT st.stellen_id, ks.stellenbez, ks.bereich, ks.firma, ks.ort, ks.plz
            FROM krit_suche AS ks
               LEFT JOIN krit_suche_id_stellen_id AS ki_si ON ki_si.krit_suche_id=ks.krit_suche_id
                 RIGHT JOIN stellenanzeigen as st ON   st.stellen_id=ki_si.stellen_id  ORDER BY $sortierung");

            Dabei gehe ich davon aus, dass die Tabelle
             krit_suche_id_stellen_id alias ki_si die Felder
              krit_suche_id und stellen_id
            für die Schlussel hat; falls die dort anders heissen, musst du das bei den ON - Bed. anpassen.

            Bin mir bei dem Right-Join nicht ganz sicher, so sollte er dir auch Stellen liefern, zu denen keine Daten in krit_suche stehen. Sonst auch LEFT/INNER probieren.

            ps. Ynwa is kein Name sondern die Abkürzung eines sehr bekannten Fußball-Liedes.

            in diesem Sinne

            1. Hallo Vimes,

              YES,YES, YES...

              Ich habe gerade einen Freudentanz für dich abgehalten. Vielleicht hast du es ja innerlich gespürt.

              Die Abfrage ist genau so, wie ich sie mir seit heute morgen vorgestellt habe und funktioniert perfekt. (MIT LEFT anstatt RIGHT JOIN) Danke!

              Es tut mir leid, dass ich die entscheidende Stelle nicht erwähnt habe und dich so auf den Holzweg geführt habe. Sorry!

              Nun werde ich diesen komischen 3-fach join mal genau analysieren. Vielleicht fällt mir ja eine Gesetzmäßigkeit auf, die ich mir irgendwie einprägem kann.

              Ich hoffe es kommt der Tag, an dem ich mich revangieren kann...

              Grüße aus Braunschweig

              Fabian

              PS: Das Lied kenne ich leider nicht.

              1. Hallo Vimes,

                Dann tanz mal schön

                PS: Das Lied kenne ich leider nicht.

                Als Braunschweiger nicht? Kenne rund 3000 Braunschweiger, die das bestimmt nicht vergessen werden ..
                ich sag nur 7:1 :-))))))

                You Never Walk Alone!

                Gruß aus Hamburg