*jiriki*: MySQL: Select aus zwei Tabellen

Moin, ich hab folgendes Problem:
Ich hab zwei Tabellen, "horses" und "bids". Jetzt möchte ich zu jedem Pferd aus "horses" das zugehörige höchste bisherige Gebot ermitteln (über MAX(bids.bid)) und dann eine Gesamtabfrage haben, in der dieses höchste Gebot an die zugehörigen Pferdedatensätze angehängt wird. Dazu hab ich bisher leider noch eine temporäre Tabelle in Gebrauch, die mir erst zu jeder PferdeID das zugehörige Maximum ermittelt.

Sieht folgendermaßen aus:

CREATE TABLE tmp
SELECT hID, MAX( time ) as time, MAX( bid ) AS current
FROM auction_bids
WHERE DATE_FORMAT( time, '%Y%m%d' ) < DATE_FORMAT( NOW(), '%Y%m%d' )
GROUP BY hID;

und dann die Gesamtabfrage

SELECT auction_horses.id, auction_horses.name as name, auction_horses.minimum, auction_horses.deadline as deadline, tmp.current, tmp.time as time
FROM auction_horses, auction_bids, tmp
WHERE auction_horses.id = tmp.hID
AND auction_bids.bid = tmp.current
ORDER BY deadline DESC, time DESC;

Ich hoff, die Spaltenbezeichnungen sind selbsterklärend.

Ich würde mir die Erzeugung der Temp-Tabelle gern sparen. Wenn also jemand noch ne elegantere Lösung im Petto hat, bitte sagen wies geht.

Danke, *jiriki*

  1. Hallo *jiriki*.

    Ich würde mir die Erzeugung der Temp-Tabelle gern sparen. Wenn also jemand noch ne elegantere Lösung im Petto hat, bitte sagen wies geht.

    Ich habe zwar momentan keinen Link parat, aber der Begriff, den du suchst, lautet „INNER JOIN“.

    Gruß, Ashura

    --
    Selfcode: sh:( fo:) ch:? rl:( br:^ n4:& ie:{ mo:) va:) de:> zu:) fl:( ss:| ls:[ js:|
    30 Days to becoming an Opera8 Lover -- Day 19: Notes
    Meine Browser: Opera 8.01 | Firefox 1.0.4 | Lynx 2.8.3 | Netscape 4.7 | IE 6.0
    [Deshalb frei! - Argumente pro freie Software]
  2. yo,

    Ich hab zwei Tabellen, "horses" und "bids". Jetzt möchte ich zu jedem Pferd aus "horses" das zugehörige höchste bisherige Gebot ermitteln (über MAX(bids.bid))

    bids.bid hört sich schwer nach einer eindeutigen id des datensatzes an und ist somit nicht das höchste gebot. sollte dort denoch gebote stehen, so ist der name der spalte sehr, sehr verwirrend. desweiteren sollte es zwischen den beiden tabellen auction_horses und auction_bids eine verbindung geben und zwar nicht indirekt über die tmp tabelle. es handelt sich dabei um eine 1:n verbindung, ein pferd kann mehrere gebote haben, aber ein gebot gehört immer nur zu ein pferd. insofern sollte sich der fremdschlüssel in der auction_bids tabelle befinden.

    es geht mit einer abfrage, die frage ist, ob dein dbms schon unterabfragen kann. falls nicht, könte man das eventuell mit einem GROUP BY lösen.

    CREATE TABLE tmp
    SELECT hID, MAX( time ) as time, MAX( bid ) AS current

    die beiden aggregat-funktionen sind vollkommen unabhängig voneinander, sprich die MAX(time) muss nicht im gleichen datensatz wie die MAX(bid) stehen. ich weiß nicht, ob du das bedacht hast.

    also mein tipp, das tabellen-design noch mal überdenken und die 1:n beziehung abbilden. dann geht das auch sicherlich ohne tmp tabelle. wäre interessant zu wissen, wie deine auction_bids tabelle aussieht.

    Ilja

    1. bids.bid hört sich schwer nach einer eindeutigen id des datensatzes an

      Jo, in der Bid-Tabelle bekommt jedes Bid(Gebot) eine eigene ID

      desweiteren sollte es zwischen den beiden tabellen auction_horses und auction_bids eine verbindung geben und zwar nicht indirekt über die tmp tabelle

      Die gibt es. In der Bid-Tabelle gibt es ein Feld hID, welches die ID des zugehörigen Pferdes referenziert.

      es handelt sich dabei um eine 1:n verbindung, ein pferd kann mehrere gebote haben, aber ein gebot gehört immer nur zu ein pferd. insofern sollte sich der fremdschlüssel in der auction_bids tabelle befinden.

      So ist es.

      es geht mit einer abfrage, die frage ist, ob dein dbms schon unterabfragen kann. falls nicht, könte man das eventuell mit einem

      GROUP BY lösen.

      Leider nicht. Geht erst ab MySQL 4.1x oder so. Hab noch 4.0x.

      CREATE TABLE tmp
      SELECT hID, MAX( time ) as time, MAX( bid ) AS current

      die beiden aggregat-funktionen sind vollkommen unabhängig voneinander, sprich die MAX(time) muss nicht im gleichen datensatz wie die MAX(bid) stehen. ich weiß nicht, ob du das bedacht hast.

      Ist bedacht, denn ein neues Gebot wird nur in die Tabelle eingetragen, wenns auch höher ist, als das vorhergehende.

      also mein tipp, das tabellen-design noch mal überdenken und die 1:n beziehung abbilden. dann geht das auch sicherlich ohne tmp tabelle. wäre interessant zu wissen, wie deine auction_bids tabelle aussieht.

      Die auction_bids hat folgende Felder:
      ID         Schlüssel
      hID        Referenz auf PferdeID
      rID        Referenz auf Bieter
      bid        Gebot
      time       Eintragszeit mit TIMESTAMP

      Gruß, *jiriki*

      1. yo,

        Jo, in der Bid-Tabelle bekommt jedes Bid(Gebot) eine eigene ID

        ok, geklärt, der spaltenname bid für ein gebot ist aber sehr verwirrend. klingt mehr nach einem schlüssel und das würde ich ändern.

        Ist bedacht, denn ein neues Gebot wird nur in die Tabelle eingetragen, wenns auch höher ist, als das vorhergehende.

        sehr risikoreich, da eventuell eingaben erfolgen und als transaktion noch nicht ganz abgeschlossen sind, es aber schon zu neuen eingaben kommt, die im gebot niedriger sind. das würde ich versuchen anders zu lösen.

        versuch mal folgendes, ohne gewähr und mit oben besagten zu beachten:

        SELECT auction_horses.id, auction_horses.name, auction_horses.minimum, auction_horses.deadline, MAX(time) as time, MAX(bid) AS Gebot
        FROM auction_horses, auction_bids
        WHERE auction_horses.id = auction_bids.hid
        GROUP BY auction_horses.id, auction_horses.name, auction_horses.minimum, auction_horses.deadline

        Ilja