Announcement

Collapse
No announcement yet.

Datenbankabfrage über 2 Tabellen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Datenbankabfrage über 2 Tabellen

    Hallo,

    jetzt google und such ich schon wieder seit Stunden herum, komm aber nicht auf die Lösung des Problems. Ich würde mich freuen, wenn mir jemand helfen könnte.

    Folgendes:
    Ich habe 3 Tabellen (images, payments, recipes) und habe derzeit 2 getrennte SELECT-Abfragen, welche ich zu einer machen möchte. Leider klappt das nicht so ganz.

    1. Abfrage
    Code:
    $sql = 'SELECT `recipes`.`id`, `recipes`.`title`, `recipes`.`category`, `recipes`.`cuisine`, `recipes`.`difficulty`, `recipes`.`description`, `recipes`.`rating`, `recipes`.`price` FROM `recipes` LEFT OUTER JOIN payments p ON p.recipe_id = recipes.id AND p.user_id = ? WHERE p.id IS NULL ORDER  BY `recipes`.`id` ASC LIMIT  ?, ?';
    $show_recipes = $db->prepare($sql);
    $show_recipes->bind_param('iii', $_SESSION['userid'], $limit, $r_per_page);
    2. Abfrage
    Code:
    $sql = 'SELECT `images`.`image_name` FROM `images` LEFT OUTER JOIN payments p ON p.recipe_id = images.recipe_id AND p.user_id = ? WHERE p.id IS NULL  AND `images`.`preview` = 1 ORDER BY `images`.`recipe_id` ASC LIMIT  ?, ?';
    $get_image = $db->prepare($sql);
    $get_image->bind_param('iii', $_SESSION['userid'], $limit, $r_per_page);
    So wie es jetzt ist funktioniert alles. Bei der 1. Abfrage werden die Rezept-Infos geladen die in der Tabelle payments mit der User-ID noch NICHT gespeichert sind. Payments sieht so aus: id, user_id, recipe_id
    Und es werden eben nur jene Rezepte geladen die in payments dem user noch NICHT zugeordnet sind.

    Gleiches soll jetzt mit den Bilder-Namen geschehen. Es sollen all jene Bilder-Namen aus images geladen werden, die zu den Rezepten gehören die der Benutzer noch nicht in payments stehen hat.

    Ich dachte mir dass man diese beiden Abfragen vereinen kann, da nur eine WHERE-Bedingung hinzugefügt werden müsste und ein SELECT (images.image_name). Leider klappt das nicht wirklich...

    Hat jemand einen Vorschlag? Ich wäre sehr dankbar für jede Hilfe!

    MfG Toni

  • #2
    Originally posted by Toni91 View Post
    Leider klappt das nicht wirklich...
    Das ist ja doof! Versuch es doch mal so, dass es klappt!

    Das würde ich ja jetzt so geschrieben haben, aber man sollte ja sachlich bleiben:
    Dein Code ist schlecht formatiert, man kann es nicht gut lesen.
    (Ich schreib das nicht nur, weil ich es gern angenehm habe beim Lesen, ich bin auch der Meinung, das viele Post gar nicht hier landen würden, wenn der Ersteller sich selbst den Gefallen täte, es so zu schreiben, dass man keine 3 Monitor breite Bleiwüste vor sich hat.)

    Du hast keine Fehlermeldung geliefert. Sollen wir die raten?
    (Die Anzahl Deiner Beiträge lässt vermuten, dass Du besser wissen solltest, wie es geht)

    Es gibt keine Bespieldaten, kein Datenmodell....
    Gruß, defo

    Comment


    • #3
      Darauf werde ich jetzt mal nicht weiter eingehen. Du bist auch so jemand der seinen Senf dazu gibt und dann erst nichts hilfreiches leistet... :-)
      Ich hoffe du kannst diesen langen Satz lesen und musst dir nicht extra wegen mir einen 2. Monitor anschaffen :-)

      Aber dennoch:
      1. Abfrage:

      Code:
      'SELECT `recipes`.`id`, `recipes`.`weiterespalten`
      FROM `recipes`
      LEFT OUTER JOIN payments p
      ON p.recipe_id = recipes.id
      AND p.user_id = 2
      WHERE p.id IS NULL'
      2. Abfrage:

      Code:
      'SELECT `images`.`name`
      FROM `images`
      LEFT OUTER JOIN payments p
      ON p.recipe_id = images.recipe_id
      AND p.user_id = 2 WHERE p.id IS NULL
      AND `images`.`preview` = 1'
      Ich glaube, um die Frage beantworten zu können Bedarf es keinen Beispieldaten, da es hierbei nur darum geht die beiden SELECT-Anweisungen zu einer zu machen.

      Tabelle payments: id (INT), user_id (INT), recipe_id (INT)
      Tabelle recipes: id (INT), title (VARCHAR), description (TEXT), price (DECIMAL)
      Tabelle images: id (INT), recipe_id (INT), name (VARCHAR), preview (INT)

      Bei der 1. Abfrage werden, wie schon im 1. Post erwähnt, jene Recipes abgerufen, die noch nicht in der payments mit der dazugehörigen user_id stehen.
      Bei der 2. Abfrage werden jene Namen der Bilder abgerufen, deren dazugehöriges Rezept noch nicht in der payments mit der dazugehörigen user_id stehen.
      Außerdem werden nur jene Bildernamen abgerufen, die im Feld preview den Wert 1 haben.

      Beides klappt mit den seperaten Abfragen, jedoch schaffe ich es nicht beide zu kombinieren, dass sowohl die Rezept-Inhalt abgerufen werden als auch die Bildernamen aus images.

      Ich hoffe es ist jetzt verständlicher und du oder jemand anderer kann mir dabei helfen.

      MfG Toni

      Comment


      • #4
        Hallo,
        Originally posted by Toni91 View Post
        ...Ich glaube, um die Frage beantworten zu können Bedarf es keinen Beispieldaten, da es hierbei nur darum geht die beiden SELECT-Anweisungen zu einer zu machen.
        Wenn du der Meinung bist die Nachfragen deiner Helfer ignorieren zu können und selbst am besten weisst, was zur Beantwortung der Frage notwendig ist und was nicht, dann wirst du deine Frage selbst beantworten müssen!

        Originally posted by Toni91 View Post
        ... Beides klappt mit den seperaten Abfragen, jedoch schaffe ich es nicht beide zu kombinieren, ...
        Was verstehst du unter "kombinieren"? Deine Abfragen passen schon rein Formal (Anzahl der Spalten) nicht zueinander.

        Gruß Falk
        Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

        Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

        Comment


        • #5
          Ich weiss zwar nicht was du mit "kombinieren" meinst aber vielleicht hilft dir dieser Ansatz weiter:

          [highlight=sql]
          select *
          from
          (SELECT `recipes`.`id`, `recipes`.`weiterespalten`
          FROM `recipes`
          LEFT OUTER JOIN payments p
          ON p.recipe_id = recipes.id
          AND p.user_id = 2
          WHERE p.id IS NULL)
          join
          (SELECT `images`.`name`
          FROM `images`
          LEFT OUTER JOIN payments p
          ON p.recipe_id = images.recipe_id
          AND p.user_id = 2 WHERE p.id IS NULL
          AND `images`.`preview` = 1)
          on ...
          [/highlight]

          Gruss

          Comment


          • #6
            Hallo,

            also ich habe jetzt mal deinen Ansatz verwendet, der schaut bei mir jetzt so aus...

            [highlight=sql]
            $sql = 'SELECT * FROM
            (SELECT `recipes`.`id`, `recipes`.`weiterespalten`
            FROM `recipes`
            LEFT OUTER JOIN payments p
            ON p.recipe_id = recipes.id
            AND p.user_id = ?
            WHERE p.id IS NULL)
            JOIN
            (SELECT `images`.`image_name`
            FROM `images`
            LEFT OUTER JOIN payments p
            ON p.recipe_id = images.recipe_id
            AND p.user_id = ?
            WHERE p.id IS NULL
            AND `images`.`preview` = 1)
            ON p.recipe_id = recipes.id
            AND p.user_id = ?
            WHERE p.id IS NULL';

            $show_recipes = $db->prepare($sql);

            $show_recipes->bind_param('iii', $_SESSION['userid'], $_SESSION['userid'], $_SESSION['userid']);
            [/highlight]

            Folgender Fehler: Fatal error: Call to a member function bind_param() on a non-object in /home/user1/domain.com/include/index.php on line 48

            Zeile 48 ist: $show_recipes->bind_param(....); Daran liegts aber nicht, da der Fehler in der Abfrage selbst ist.

            Comment


            • #7
              Originally posted by Toni91 View Post
              ...Daran liegts aber nicht, da der Fehler in der Abfrage selbst ist.
              Dann wäre es wohl besser die Fehlermeldung der Abfrage zu posten...
              Da wir hier von MySQL reden, wird es aber sicherlich daran liegen, dass die Subqueries über keine Aliase verfügen (was bei MySQL Pflicht ist). Auch macht die ON-Klausel des äusseren Join keinen Sinn, da in diesem Kontext weder der Bezeichner "p" noch "recipes" bekannt ist. Hier müssten eher die (fehlenden) Aliase stehen. (Gleiches trifft natürlich auf die WHERE-Klausel zu).

              Gruß Falk
              Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

              Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

              Comment


              • #8
                Da ich die Abfrage von Wernfried übernommen habe und er am Ende eine ON-Klausel hatte mit 3 Punkten wusste ich nicht was ich hier eintragen sollte

                Die derzeitige Abfrage sieht so aus, phpMyAdmin sagt dazu folgendes:
                #1248 - Every derived table must have its own alias
                Aber ich habe recipes doch den Alias r gegeben oder mache ich etwas falsch?
                Ich wäre echt dankbar wenn man mir sobald wie möglich zur Lösung verhelfen könnte, da wir sonst mit unserem Projekt nicht weitermachen können.

                [highlight=sql]
                SELECT * FROM
                (SELECT `recipes`.`id`, `recipes`.`title`
                FROM recipes r
                LEFT OUTER JOIN payments p
                ON p.recipe_id = r.id
                AND p.user_id = 1
                WHERE p.id IS NULL)
                JOIN
                (SELECT `images`.`image_name`
                FROM images i
                LEFT OUTER JOIN payments p
                ON p.recipe_id = i.recipe_id
                AND p.user_id = 1
                WHERE p.id IS NULL
                AND i.preview = 1)
                [/highlight]

                Comment


                • #9
                  Originally posted by Toni91 View Post
                  #1248 - Every derived table must have its own alias
                  Aber ich habe recipes doch den Alias r gegeben oder mache ich etwas falsch?
                  Die Fehlermeldung sagt, dass jede abgeleitete Tabelle ihren eigenen Alias benötigt. Genau dasselbe hat auch Falk gesagt:
                  wird es aber sicherlich daran liegen, dass die Subqueries über keine Aliase verfügen (was bei MySQL Pflicht ist).
                  Du benötigst so etwas (wie p1 und p2 in meinem Beispiel):
                  [highlight=sql]
                  SELECT * FROM
                  (SELECT `recipes`.`id`, `recipes`.`title`
                  FROM recipes r
                  LEFT OUTER JOIN payments p
                  ON p.recipe_id = r.id
                  AND p.user_id = 1
                  WHERE p.id IS NULL) AS p1
                  JOIN
                  (SELECT `images`.`image_name`
                  FROM images i
                  LEFT OUTER JOIN payments p
                  ON p.recipe_id = i.recipe_id
                  AND p.user_id = 1
                  WHERE p.id IS NULL
                  AND i.preview = 1) AS p2
                  [/highlight]
                  Dann musst du - ebenfalls wie Falk sagte - diese Aliase in ON und WHERE verwenden. Jürgen

                  PS. Glaubst du, dass dein Drängeln hilfreich ist? An wem liegt es wohl, wenn ihr nicht weiterkommt - etwa an den potenziellen Helfern?
                  Zuletzt editiert von Jürgen Thomas; 26.11.2012, 14:21. Reason: PS

                  Comment


                  • #10
                    Hallo,

                    Wenn ich die oben genannte Abfrage verwende kommt als Meldung: Unknown column 'recipes.id' in 'field list'


                    PS: Ich drängle nicht, ich bin nur davon ausgegangen dass es recht einfach sein sollte diese 2 SELECT-Anweisungen zusammenzufassen.
                    Zuletzt editiert von Toni91; 26.11.2012, 14:29.

                    Comment


                    • #11
                      Die fertige Lösung wollte ich auch nicht angeben, schliesslich möchte ich dass du die Lösung verstehst und etwas dabei lernst
                      Die Sub-Selects benötigen einen Alias und es müssen die Spalten selektiert werden auf welchen verbunden wird.

                      Ungefähr so:
                      [highlight=sql]
                      SELECT * FROM
                      (SELECT `recipes`.`id`, `recipes`.`title`
                      FROM recipes r
                      LEFT OUTER JOIN payments p
                      ON p.recipe_id = r.id
                      AND p.user_id = 1
                      WHERE p.id IS NULL) tab_a
                      JOIN
                      (SELECT `images`.`image_name`, `images`.`recipes_id`
                      FROM images i
                      LEFT OUTER JOIN payments p
                      ON p.recipe_id = i.recipe_id
                      AND p.user_id = 1
                      WHERE p.id IS NULL
                      AND i.preview = 1) tab_b
                      ON tab_a.id = tab_b.recipes_id
                      [/highlight]

                      Gruss

                      Comment


                      • #12
                        Hallo,

                        also ich glaub jetzt hab ichs verstanden
                        Ich hatte bisher noch nicht so viel mit MySQL zu tun bzw. das was ich damit gemacht habe waren mehr oder weniger "einfache" Abfragen ohne JOINS usw.

                        Danke für deine Hilfe Wernfried, jetzt funktioniert es :-)

                        Lg Toni

                        Comment

                        Working...
                        X