Viennamade: Ersatz für Subselect

Hallo liebe Forumer!

Ich habe einen Abfragebedarf auf 3 Tabellen:

Bilder        Copyright    Bildertexte                Sprachen
-------------------------  -------------------------  ----------
1 Kuh.jpg     false        1 Das ist eine Kuh      1  1 DE
2 Hund.jpg    true         1 This is a cow         2  2 EN
3 Schwein.jpg false        2 Das ist ein Hund      1
                           2 This is a dog         2
                           3 Das ist ein Schwein   1
                           3 This is a pig         2

Eine Funktion erhält den Bildnamen und das Sprachkürzel, sagen wir Kuh.jpg und EN. Das Ergebnis soll sein false (keine Copyright) und "This is a cow". Nicht zu jedem Bild gibts Bildertexte in allen Sprachen.
Da ich MySQL Version 3.23.52-log verwende, geht kein Subselect auf Bildertexte und Sprachen.
Muß ich jetzt wirklich zuerst das Copyright und die BildID (1/2/3) mit Kuh.jpg holen und dann, mit einer 2. Abfrage den Bildertext (innerjoin Texte/Sprachen)?

Beste Grüße
Viennamade

  1. Hello,

    man kann (manche) subselects in MySQL durch einen SelfJoin ersetzen.

    Dazu musst Du die Tabelle unter zwei Aliasen zweimal eröffnen und dann dazwischen einen möglichst intelligenten Join (auch mit where) herstellen.

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
  2. yo,

    Muß ich jetzt wirklich zuerst das Copyright und die BildID (1/2/3) mit Kuh.jpg holen und dann, mit einer 2. Abfrage den Bildertext (innerjoin Texte/Sprachen)?

    nein, equi joins sollten zu deinem gewünschten ergebnis führen also nur eine abfrage.

    Ilja

    1. Hallo!

      Danke für Eure Antworten.

      Muß ich jetzt wirklich zuerst das Copyright und die BildID (1/2/3) mit Kuh.jpg holen und dann, mit einer 2. Abfrage den Bildertext (innerjoin Texte/Sprachen)?

      nein, equi joins sollten zu deinem gewünschten ergebnis führen also nur eine abfrage.

      Also mein Versuch sieht so aus

      SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title,s.Kuerzel FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) INNER JOIN Sprachen AS s ON (bitxt.Sprache = s.LangNr) WHERE bi.osname ='x96.gif' AND (s.Kuerzel = 'EN')

      und endet damit, daß nur Datensätze von Bildern zurückgegeben werden, zu denen tatsächlich Bildertexte vorhanden sind :-(

      Beste Grüße
      Viennamde

      1. yo,

        SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title,s.Kuerzel FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) INNER JOIN Sprachen AS s ON (bitxt.Sprache = s.LangNr) WHERE bi.osname ='x96.gif' AND (s.Kuerzel = 'EN')

        der Outer Joins ist nur notwendig notwendig, wenn es zu einem bild keine entsprechenden bildertext gibt, was ich aber an deinen tabellen auf den ersten blick nicht herleiten kann. es sieht so aus, als wenn jedes bild auch einen tex hat. da du das aber als problem erwähnst, scheint es der fall zu sein. damit wird dein problem der zweite INNER JOIN sein. wenn du erst eien LEFT JOIN machst, werden eventuell NULL werte eingesetzt. und diese NULL werte werden auch bei einem INNER JOIN nie auf gleichheit teffen.

        zum anderen sieht dein daten-design auf den ersten blick nicht "sauber" aus, aber das ist mehr ein gefühl.

        SELECT ....
        FROM bilder AS bi
        LEFT JOIN bildertexte AS bitxt ON (bi.picnr = bitxt.bildnr)
        LEFT JOIN  sprachen AS s ON (bitxt.sprache = s.langnr)
        WHERE bi.osname = 'x96.gif' AND s.kuerzel= 'EN'

        Ilja

        1. Hallo Ilja!

          Danke für die Antwort.

          SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title,s.Kuerzel FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) INNER JOIN Sprachen AS s ON (bitxt.Sprache = s.LangNr) WHERE bi.osname ='x96.gif' AND (s.Kuerzel = 'EN')

          der Outer Joins ist nur notwendig notwendig, wenn es zu einem bild keine entsprechenden bildertext gibt, ...

          Ja das kann sein, ein Bild kann keine Entsprechung in Texte haben, oder eine, oder mehrere (für mehrere Sprachen).

          was ich aber an deinen tabellen auf den ersten blick nicht herleiten kann.

          Ich hoffe jetzt besser darzustellen:

          Tabelle Bilder             Tabelle  Bildertexte             Tabelle Sprachen
          ID osname      pxhoehe      ID Text                Sprache  ID Kuerzel
          -------------------------  -------------------------------  ----------------
          1  Kuh.jpg     400          1  Das ist eine Kuh      1      1  DE
          2  Hund.jpg    450          1  This is a cow         2      2  EN
          3  Schwein.jpg 500          3  Das ist ein Schwein   1
          4  Gans        600          4  This is a goose       2

          damit wird dein problem der zweite INNER JOIN sein. wenn du erst einen LEFT JOIN machst, werden eventuell NULL werte eingesetzt. und diese NULL werte werden auch bei einem INNER JOIN nie auf gleichheit teffen.

          Stimmt, egal ob der erste Join ein LEFT ist oder nicht, ich bekomme immer nur jene Bilder die mindestens eine Zeile in Bildertexte haben.
          Weil eben - wie Du sagst - die Nullwerte aus Bildertexte nie eine Entprechung in der Tabelle Sprache finden.

          Nur, wie soll ich das lösen? Ich versuchte eben ohne Erfolg das Problem mit den nicht vorhandenen Bildertexten so in den Griff zu bekommen:
          $sql="SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title,s.Kuerzel FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) LEFT JOIN Sprachen AS s ON (bitxt.Sprache = s.LangNr) WHERE bi.osname ='" . $osname . "' AND (s.Kuerzel = '" . $lang . "' OR isnull(bitxt.PicID))";
          So richtig weiß ich nicht, ob und wo ich isnull einsetzen soll, denn natürlich will ich das Bild jedenfalls haben, egal ob mit oder ohne Text.

          Leider ohne Erfolg ....
          Beste Grüße
          Viennamade

          1. yo,

            Leider ohne Erfolg ....

            überall LEFT JOIN zu verwenden ist schon de richtige weg. das OR isnull(bitxt.PicID) weglassen, zumal die äußeren klammern da komisch gesetzt sind. was genau heißt denb nun kein erfolg ?

            Ilja

            1. Hallo Ilja!

              Leider ohne Erfolg ....

              überall LEFT JOIN zu verwenden ist schon de richtige weg. das OR isnull(bitxt.PicID) weglassen, zumal die äußeren klammern da komisch gesetzt sind. was genau heißt denb nun kein erfolg ?

              Ohne isnull erhalte ich das gleich unerwünschte Ergebnis:
              SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) LEFT JOIN Sprachen AS s ON (bitxt.Sprache = s.LangNr) WHERE bi.osname ='x2b.jpg' AND s.Kuerzel = 'EN'

              Ohne Erfolg bedeutet, daß ich nur Datensätze bekomme wo es mindestens eine Zeile in der Tabelle Bildertexte gibt. Aufgrund Deiner Postings sehe ich das Problem dahingend, daß die Datensätze aus Bildertexte mitunter NULL sind und bei diesen Datensätzen der Abgleich mit dem Sprachkennzeichen nicht funktionieren kann.
              Habe nur leider keine Ahnung wie das zu lösen ist :-(

              Beste Grüße
              Viennamade

              1. yo,

                Ohne Erfolg bedeutet, daß ich nur Datensätze bekomme wo es mindestens eine Zeile in der Tabelle Bildertexte gibt.

                nein, das sollte nicht passieren, dann muss noch woanders ein fehler vorliegen vielleicht spaltennamen verwechselt. LEFT JOIN sorgt dafür, dass alle datensätze der linken tabelle genommen werden, egal ob es passende datensätze in de rechten tabelle gibt. ich denke mal, einfach noch mal deine dateninhalte durchgehen. ein tip, du kannst den join est einmal über nur zwei tabellen durchführen und dann zu drei übergehen, wenn du das gewünschte ergebnis mit zwie tabllen erreicht hast.

                Ilja

                1. Hallo!

                  Ohne Erfolg bedeutet, daß ich nur Datensätze bekomme wo es mindestens eine Zeile in der Tabelle Bildertexte gibt.

                  nein, das sollte nicht passieren, dann muss noch woanders ein fehler vorliegen vielleicht spaltennamen verwechselt. LEFT JOIN sorgt dafür, dass alle datensätze der linken tabelle genommen werden, egal ob es passende datensätze in de rechten tabelle gibt. ich denke mal, einfach noch mal deine dateninhalte durchgehen. ein tip, du kannst den join est einmal über nur zwei tabellen durchführen und dann zu drei übergehen, wenn du das gewünschte ergebnis mit zwie tabllen erreicht hast.

                  ein tip, du kannst den join est einmal über nur zwei tabellen durchführen und dann zu drei übergehen, wenn du das gewünschte ergebnis mit zwie tabllen erreicht hast.

                  Ich habe Deinen Tipp (Danke) umgesetzt. Das heißt, ich habe mal die dritte Tabelle weggelassen und mit 2 Bildern getestet:
                    x95.gif hat einen Bildertext mit dem Sprachkennzeichen 1 in der Tabelle Bildertext
                    x96.gif hat keinen Bildertext

                  Zum Testen gebe ich am Bildschirm wie folgt aus:

                  if ($list->numRows())
                    {
                      while ($sql_fetch_rows = $list->fetch(MYSQL_ASSOC))
                        {
                        echo '<pre>';
                        print_r($sql_fetch_rows);
                        echo '<pre>';
                        }

                  Für x95.gif wird ein Datensatz ausgegeben:
                   SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) WHERE bi.osname ='x95.gif' AND bitxt.Sprache = 1

                  Für x96.gif hingegegen keiner:
                  SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) WHERE bi.osname ='x96.gif' AND bitxt.Sprache = 2

                  Ich verstehe es absolut nicht.

                  Bitte um Hilfe
                  Viennamade

                  1. yo,

                    Ich verstehe es absolut nicht.

                    wie gesagt, dein fehler liegt woanders, der LEFT JOIN ist der richtige ansatz.

                    AND bitxt.Sprache = 2

                    hier liegt dann auch dein fehler, du sprichst eine spalte der rechten tabelle an, die 2 sein soll. und genau dies wird den left join entgegen wirken, weil in der rechten tabelle NULL steht, wenn sie keinen entsprechenden datensatz in der rechten tabelle gefunden wird.

                    Ilja

                    1. yo,

                      AND bitxt.Sprache = 2

                      hier liegt dann auch dein fehler, du sprichst eine spalte der rechten tabelle an, die 2 sein soll. und genau dies wird den left join entgegen wirken, weil in der rechten tabelle NULL steht, wenn sie keinen entsprechenden datensatz in der rechten tabelle gefunden wird.

                      das ist natürlich quatsch was ich geschrieben habe. da muss ich noch mal morgen ran, mit weniger bier.....

                      Ilja

                      1. Hallo Ilja!

                        AND bitxt.Sprache = 2

                        hier liegt dann auch dein fehler, du sprichst eine spalte der rechten tabelle an, die 2 sein soll. und genau dies wird den left join entgegen wirken, weil in der rechten tabelle NULL steht, wenn sie keinen entsprechenden datensatz in der rechten tabelle gefunden wird.

                        das ist natürlich quatsch was ich geschrieben habe. da muss ich noch mal morgen ran, mit weniger bier.....

                        Ja Bitte!

                        Ich bin insoferne auf einem grünen Zweig, als daß ich mit dieser reduzierten Abfage ...
                          SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) WHERE bi.osname ='x96.gif' AND bitxt.Sprache = 1 OR bitxt.Sprache is null

                        ... zumindest mal in jedem Fall einen Datensatz bekomme. Wie ich da jetzt einen Join zur Tabelle Sprachen zusammenbekomme und dort nach 'EN' bzw. 'DE' Abfrage ist mir offen gesagt ein Rätsel.

                        Danke für Deine Bemühungen,
                        Viennamade

                        1. yo,

                          morgenstund hat gold im mund.

                          ... zumindest mal in jedem Fall einen Datensatz bekomme. Wie ich da jetzt einen Join zur Tabelle Sprachen zusammenbekomme und dort nach 'EN' bzw. 'DE' Abfrage ist mir offen gesagt ein Rätsel.

                          es sieht so aus, als wenn mein erster post doch nicht so ganz aus der luft gegriffen war. mich verwundert es ein wenig selbst, aber scheinbar wird die bedingung bitxt.Sprache = 1 nach dem LEFT JOIN ausgeführt und somit alle NULL datensätze in dieser spalte ausgeschlossen.

                          ausprobieren kannst du das, indem du die bedingung einfach mal wegläßt und schaust, ob du nun auch NULL werte erhälst.

                          Ilja

                          1. Hallo!

                            morgenstund hat gold im mund.

                            Na, dann hoffe ich daß meine Antwort nicht zu spät kommt :-)

                            ... zumindest mal in jedem Fall einen Datensatz bekomme. Wie ich da jetzt einen Join zur Tabelle Sprachen zusammenbekomme und dort nach 'EN' bzw. 'DE' Abfrage ist mir offen gesagt ein Rätsel.

                            es sieht so aus, als wenn mein erster post doch nicht so ganz aus der luft gegriffen war. mich verwundert es ein wenig selbst, aber scheinbar wird die bedingung bitxt.Sprache = 1 nach dem LEFT JOIN ausgeführt und somit alle NULL datensätze in dieser spalte ausgeschlossen.

                            ausprobieren kannst du das, indem du die bedingung einfach mal wegläßt und schaust, ob du nun auch NULL werte erhälst.

                            Jo, so ist es, ich erhalte NULL-Werte, wenn ich die Bedingung weglasse:

                            Tabelle Bilder             Tabelle  Bildertexte             Tabelle Sprachen
                            ID osname      pxhoehe      ID Text                Sprache  ID Kuerzel
                            -------------------------  -------------------------------  ----------------
                            1  Kuh.jpg     400          1  Das ist eine Kuh      1      1  DE
                            2  Hund.jpg    450          1  This is a cow         2      2  EN
                            3  Schwein.jpg 500          3  Das ist ein Schwein   1
                            4  Gans        600          4  This is a goose       2

                            SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) WHERE bi.osname ='Hund.jpg'

                            • bringt einen Datensatz, bitxt.alttag und bitxt.title sind leer - und das ist gut so.

                            SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) WHERE bi.osname ='Hund.jpg' AND bitxt.Sprache = 1

                            • bringt keinen Datensatz, es gibt ja auch keine Entsprechung in Bildertexte - also ist es gut.

                            SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) WHERE bi.osname ='Hund.jpg' AND bitxt.Sprache = 1 OR bitxt.Sprache is null

                            • bringt einen Datensatz, bitxt.alttag und bitxt.title sind leer - und das ist gut so.

                            Die Frage ist, wie bekomme ich es zustande, die 3. Tabelle "Sprachen" einzubinden, um »Kuerzel = 'EN'« oder »Kuerzel = 'DE'« in die Abfrage einbinden zu können.

                            Danke für Deine Bemühungen,
                            Viennamade

                            1. yo,

                              also das problem liegt daran, wie mysql den left join optimiert. versuche einfach mal die bedigungen in den join mit aufzunehmen und schau, ob es funktioniert.

                              Ilja

                              1. yo,

                                weiß nicht, ob mein letzter tipp angekommen ist, aber ich habe es selbst mal ausprobiert. wenn du die bedingung nicht nach der WHERE klausel schreibst, sondern in die join bedingung nimmst ON(...), dann klappt es.

                                Ilja

                                1. Hallo Ilja!

                                  Danke für Deine Antwort!

                                  weiß nicht, ob mein letzter tipp angekommen ist,

                                  Doch, aber ich war/bin schon richtig verzweifelt den Tipp nicht umsetzen zu können ...

                                  wenn du die bedingung nicht nach der WHERE klausel schreibst, sondern in die join bedingung nimmst ON(...), dann klappt es.

                                  Das habe ich - scheinbar falsch - versucht. Das letzte gute Ergebnis erhielt ich mit

                                  SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT OUTER JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr AND bitxt.Sprache = 2 OR bitxt.Sprache is null) WHERE bi.osname = 'x96.gif'

                                  Das funktioniert auch wunderbar, jedoch wird hier die mit der Tabelle Sprache verknüpfte Spalte (bitxt.Sparche = 2) abgefragt. Ich möchte ja mit einem zweiten Join in die Tabelle Sprache (bitxt.Sprache = s.LangNr) und dort das Sprachkürzel abfragen (s.Kuerzel = 'DE') aber da komme ich nicht weiter :-( Jeder Versuch mündet in dem alten Problem, daß bei nicht vorhandenem Bildertext gar kein Datensatz ausgegeben wird.

                                  Beste Grüße
                                  Viennamade

                                  1. yo,

                                    das "OR bitxt.Sprache is null" hat da nichts zu suchen, einfach weglassen.und was die dritte tabelle betrifft, genauso verfahren, sprich einen left join und die kriterien mit die join bedingung ON (...) aufnehmen in etwa so:

                                    LEFT JOIN sprache AS s ON (bitxt.Sprache = s.LangNr AND s.Kuerzel = 'DE')

                                    das funktioniert nicht ?

                                    Ilja

                                    1. Hallo Ilja!

                                      Ich werd noch verrückt - Du auch ? g
                                      Ausgehend von meinem letzten Versuch der gute Ergebnisse brachte, aber nur das Verknüpfungsfeld in bitxt abfragte und daher keinen Join auf "Sprachen" hatte
                                      »
                                      SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT OUTER JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr AND bitxt.Sprache = 2 OR bitxt.Sprache is null) WHERE bi.osname = 'x96.gif'
                                      «

                                      und Deiner Antwort ...

                                      das "OR bitxt.Sprache is null" hat da nichts zu suchen, einfach weglassen.und was die dritte tabelle betrifft, genauso verfahren, sprich einen left join und die kriterien mit die join bedingung ON (...) aufnehmen in etwa so:

                                      LEFT JOIN sprache AS s ON (bitxt.Sprache = s.LangNr AND s.Kuerzel = 'DE')

                                      habe ich folgendes probiert:
                                      SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT OUTER JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr AND bitxt.Sprache = 'DE') LEFT JOIN Sprachen AS s ON (bitxt.Sprache =s.LangNr AND s.Kuerzel ='DE') WHERE bi.osname = 'x96.gif'

                                      Da erhielt ich immer einen Datensatz, aber _nie_ Werte bitxt.title oder bitxt.alttag.

                                      Das erschien mir auch logisch, denn "bitxt.Sprache = 'DE'" in der ON-Clause des ersten Joins kann nie wahr sein, denn im Feld bitxt.Sprache steht ja nur 1 (für DE) oder 2 (für EN). Also nahme ich diese Bedingung raus und probierte:
                                      SELECT bi.osname,bi.pxhoehe,bi.pxbreite,bitxt.alttag,bitxt.title FROM Bilder as bi LEFT OUTER JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr) LEFT JOIN Sprachen AS s ON (bitxt.Sprache =s.LangNr AND s.Kuerzel ='EN') WHERE bi.osname = 'x95.gif
                                      Mit dem Ergebnis, daß ich immer einen Datensatz bekomme, aber mitunter falsche. Die Kombination x95.gif und englischer Bildertext des letzten Abfragestring gibt es gar nicht, aber ich erhalte den deutschen Bildertext.

                                      Danke für Deine Hilfe,
                                      Viennamade

                                      1. yo,

                                        Ich werd noch verrückt - Du auch ? g

                                        der join macht wirklich mehr probleme als er sollte.

                                        Das erschien mir auch logisch, denn "bitxt.Sprache = 'DE'" in der ON-Clause des ersten Joins kann nie wahr sein, denn im Feld bitxt.Sprache steht ja nur 1 (für DE) oder 2 (für EN). Also nahme ich diese Bedingung raus und probierte:

                                        das klnigt mir auch logisch, habe ich aus versehen dir dazu geraten oder hast du diee bedingung mit reingebracht?

                                        Mit dem Ergebnis, daß ich immer einen Datensatz bekomme, aber mitunter falsche. Die Kombination x95.gif und englischer Bildertext des letzten Abfragestring gibt es gar nicht, aber ich erhalte den deutschen Bildertext.

                                        ich glaube, du würfelst nun ein wenig die bedingungen durcheinander. sag doch noch mal in worten, welches ergebnis du willst und ich werde versuchen, die query dazu zu erstellen.

                                        Ilja

                                        1. Hallo!

                                          ich glaube, du würfelst nun ein wenig die bedingungen durcheinander. sag doch noch mal in worten, welches ergebnis du willst und ich werde versuchen, die query dazu zu erstellen.

                                          OK, ich versuche es auch klar zu formulieren. Zuerstmal der Grund der Abfrage. Es geht um eine mehrsprachige Seite mit Redaktionssystem, dort hat man auch die Möglichkeit Bilder zu verwalten, und deren alt- und title-Attribute.
                                          Also gibt es eine Funktion, welche das img-Element erstellt. An diese Funktion werden das Sprachkürzel ('DE','EN',....) und der Dateiname (xyz.jpg) übergeben.

                                          Die erste Tabelle "Bilder" enthält also pro Bild eine einzige Zeile, in einem Feld steht der Dateiname des Bildes, also xyz.jpg drinnen.
                                          Die zweite Tabelle "Bildertexte" kann pro Bild
                                           - keine Zeile haben (man hat im Redaktionssystem keinen Text eingepflegt)
                                           - soviele Zeilen haben wie Sprachen eingepflegt sind (aber auch weniger bei mangelhafter Pflege).
                                          Die 3 Tabelle "Sprachen" hat 4 Datensätze: EN,DE,ES,FR - der 2. Funktionsparameter entspricht einem dieser Kürzel.

                                          Tabelle_Bilder             Tabelle_Bildertexte              Tabelle_Sprachen
                                          ID osname      pxhoehe      ID Text                Sprache  ID Kuerzel
                                          -------------------------  -------------------------------  ----------------
                                          1  Kuh.jpg     400          1  Das ist eine Kuh      1      1  DE
                                          2  Hund.jpg    450          1  This is a cow         2      2  EN
                                          3  Schwein.jpg 500          3  Das ist ein Schwein   1
                                          4  Gans        600          4  This is a goose       2

                                          Das Resultset soll nur einen Datensatz beinhalten.
                                          Bei fn(Kuh.jpg,DE) soll im Resultset "Kuh.jpg" und "Das ist eine Kuh" drinnen stehen.
                                          Bei fn(Kuh.jpg,EN) soll im Resultset "Kuh.jpg" und "This is a Cow" drinnen stehen.
                                          Bei fn (Schwein.jpg,EN) soll im Resultset "Schwein.jpg" und "NULL" drinnen stehen.

                                          Danke für Deine Bemühungen,
                                          Viennamade

                                          1. yo,

                                            mittag vorbei und ich schlürfe gerade eine glas wein chardonnay. vielleicht etws zu früh von der tageszeit, aber man hat so seine laster.

                                            mir ist der einblick jetzt ein wenig klarer. was deine dritte tabelle angeht, so ist sie in dieser form überflüssig. zwar kann ein sprachkürzel mehreren bildertexten zugeordnet werden. aber in grunde genommen hast du nur ein feld in der dritten tabelle sprachkürzel. und dieses eine feld könnte man auch einfach in die zweite bildertexte mit übernehmen. das wäre schon mal ein lösungsweg, der auch gleich ein wenig performance bringt, weil es eine tabelle weniger gibt.

                                            die beziehung deiner zweiten tabelle ist eine 1:n beziehung, wobei der fremdschlüssel bei dir scheinbar auch gleichzeitg teil des primärschlüssel ist. das würde ich ebenfalls ändern, für die bildertexte eine eigene id anlegen und einen fremdschlüssel deklarieren, der auf die erste tabelle verweist.

                                            SELECT ...
                                            FROM bilder AS b
                                            LEFT JOIN bildertexte AS bt ON (b.id = bt.id)
                                            LEFT JOIN sprachen AS s ON (bt.sprache = s.id)

                                            dieses statement sollte dir alle bilder ausgeben, mit ihren jeweiligen bildertexten und sprachkürzel. (5 datensätze mit deinem inhalten)

                                            SELECT ...
                                            FROM bilder AS b
                                            LEFT JOIN bildertexte AS bt ON (b.id = bt.id)
                                            LEFT JOIN sprachen AS s ON (bt.sprache = s.id)
                                            WHERE b.id=1

                                            dieses statement sollte dir nur bild mit der id=1 ausgeben und seinem jeweiligen bildertexten und sprachkürzel, also das bild der kuh.(2 datensätze mit deinem inhalten)

                                            SELECT ....
                                            FROM bilder AS b
                                            LEFT JOIN bildertexte AS bt ON (b.id = bt.id)
                                            INNER JOIN sprachen AS s ON (bt.sprache = s.id)
                                            WHERE s.kuerzel='DE'

                                            dieses statement sollte dir nur bilder ausgeben, die einen deutschen text haben. (2 datensätze mit deinem inhalten)

                                            SELECT ....
                                            FROM bilder AS b
                                            LEFT JOIN bildertexte AS bt ON (b.id = bt.id)
                                            INNER JOIN sprachen AS s ON (bt.sprache = s.id)
                                            WHERE s.kuerzel='DE' AND b.id=1

                                            dieses statement sollte dir nur bild 1 ausgeben, mit seinem deutschen text (1 datensatz mit deinem inhalten)

                                            man könte nun noch mehr abfragen gestalten, aber es wäre besser, du sagst mir, welche genau du haben willst.

                                            Ilja

                                            1. Hallo Ilja!

                                              was deine dritte tabelle angeht, so ist sie in dieser form überflüssig.

                                              Auf das aktuelle Beispiel bezogen stimmt das, aber die Tabelle ist für  x andere Abfragen notwendig. Und natürlich könnte ich das Problem umschiffen, zum Beispiel die 4 Datensätze für die Sprachen (1=de,2=en, ...) in die PHP-Session einlesen und somit könnte ich - nicht nur bei "unserer" Abfrage - direkt auf die jeweilige Verknüpfung zur Sprach-ID zugreifen, hier: bitxt.Sprache.
                                              Aber ich "will" das jetzt so haben, weil ich ganz einfach wissen will wie diese Abfrage läuft und so lange Deine Bereitschaft zu Leiden vorhanden ist werde ich sie ausnützen ;-) Ich hoffe der Chardonnay mindert sie nicht und wünsche "Wohl bekomms!" :-)

                                              das würde ich ebenfalls ändern, für die bildertexte eine eigene id anlegen und einen fremdschlüssel deklarieren, der auf die erste tabelle verweist.

                                              Das gibts schon: bitxt.BildNr ist der Fremdschlüssel zu bi.PicNr, bitxt.PicID ist die eigene id.

                                              Auf das Ergebnis bezogen war dieser Abfragestring perfekt (wobei hier nur mit 2 Tabellen gearbeitet wird):

                                              "SELECT bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
                                                 FROM Bilder as bi
                                                   LEFT OUTER JOIN Bildertexte as bitxt
                                                     ON (bi.PicNr = bitxt.BildNr AND bitxt.Sprache = " . $lang . ")
                                                 WHERE bi.osname = '" . $osname . "'"

                                              Er führte zu korrekten Datensätzen wie
                                              -  bei $osname='x96.gif' und $lang = 1:
                                                 => $result: ['osname']=x96.gif, ['alttag']=''
                                                 ('alttag' ist leer, da kein bitxt.Datensatz mit Sprache 1 (=DE) für x96.gif vorhanden.)
                                              -  bei $osname='x95.gif' und $lang = 1:
                                                 => $result: ['osname']=x95.gif, ['alttag']='Das ist eine Kuh'
                                                 (alttag hat Inhalt, da ein bitxt.Datensatz mit Sprache 1 (=DE) für x95.gif vorhanden.)
                                              -  bei $osname='x96.gif' und $lang = 2:
                                                 => $result: ['osname']=x95.gif, ['alttag']='This is a cow'
                                                 (alttag hat Inhalt, da ein bitxt.Datensatz mit Sprache 2 (=EN) für x95.gif vorhanden.)

                                              Wie gesagt, perfekte Ergebnisse, also

                                              • immer ein einziger Datensatz,
                                              • bitxt leer wenn kein bitxt.Sprache mit $lang für das enstprechende Bild ($osname) vorhanden ist,
                                              • bitxt mit Inhalt, wenn Datensatz mit bitxt.Sprache == $lang für das gewünschte Bild vorhanden ist.

                                              Aber das ganze muß doch auch möglich sein, wenn man die 3. Tabelle "Sprachen" hernimmt und so nicht mit 1,2,3,4 sondernd mit 'de','en',... abfrägt.
                                              Denn die Tabelle Sprachen hat die id 'LangNr' und im Feld bitxt.Sprache stehen diese Sprach-IDs drinnen.

                                              man könte nun noch mehr abfragen gestalten, aber es wäre besser, du sagst mir, welche genau du haben willst.

                                              Bitte frage mich, wenn ich es noch nicht richtig rübergebracht habe.

                                              Danke Ilja
                                              Viennamade

                                              1. yo,

                                                Ich hoffe der Chardonnay mindert sie nicht und wünsche "Wohl bekomms!" :-)

                                                der chardonnay ist alle, nun ist ein fusel wein dran, so ein riesling....

                                                Aber das ganze muß doch auch möglich sein, wenn man die 3. Tabelle "Sprachen" hernimmt und so nicht mit 1,2,3,4 sondernd mit 'de','en',... abfrägt.

                                                ist es auch. dafür musst du einen weiteren left join machen von bildertexte auf sprachen.

                                                SELECT bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
                                                FROM Bilder as bi
                                                LEFT OUTER JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr AND bitxt.Sprache = " . $lang . ")
                                                LEFT OUTER JOIN sprachen AS s ON (bitxt.sprache = s.id)
                                                WHERE bi.osname = '" . $osname . "'"

                                                was genau haut den hierbei nicht hin ?

                                                Ilja

                                                1. Hallo!

                                                  Ich hoffe der Chardonnay mindert sie nicht und wünsche "Wohl bekomms!" :-)
                                                  der chardonnay ist alle, nun ist ein fusel wein dran, so ein riesling....

                                                  Komm her, im Namen meiner Stadt sind die beiden mittleren Buchstaben verwechselt worden;-) Und übertreibs nicht!

                                                  Aber das ganze muß doch auch möglich sein, wenn man die 3. Tabelle "Sprachen" hernimmt und so nicht mit 1,2,3,4 sondernd mit 'de','en',... abfrägt.

                                                  ist es auch. dafür musst du einen weiteren left join machen von bildertexte auf sprachen.

                                                  SELECT bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
                                                  FROM Bilder as bi
                                                  LEFT OUTER JOIN Bildertexte as bitxt ON (bi.PicNr = bitxt.BildNr AND bitxt.Sprache = " . $lang . ")
                                                  LEFT OUTER JOIN sprachen AS s ON (bitxt.sprache = s.id)              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                                  WHERE bi.osname = '" . $osname . "'"
                                                  was genau haut den hierbei nicht hin ?

                                                  Nix :-( Wie gewünscht bekomme ich immer einen _einzigen_ Datensatz mit korrekten Daten aus der Tabelle Bilder, aber die Felder aus Bildertexte sind immer leer. Ist auch logisch, denn die markierte ON-Clause (s.o.) ist nie wahr, denn in bitxt.Sprache stehen ja die Ziffern 1, 2, 3 oder 4 (für de,en,fr,es) drinnen. In der Tabelle Sprachen wiederum gibts 4 Datensätze der id's 1, 2, 3 und 4 sind und in einer weiteren Spalte stehen eben die Sprachkürzel die abgefragt werden sollten.

                                                  :-( und Danke!
                                                  Viennamade

                                                  1. yo,

                                                    Nix :-(

                                                    also jetzt verstehe ich nichts mehr, alle ok ? wonach haben wir gesucht ?

                                                    Ilja

                                                    1. Hallo Ilja!

                                                      Nix :-(

                                                      also jetzt verstehe ich nichts mehr, alle ok ? wonach haben wir gesucht ?

                                                      Bin ich jetzt der Hilfersteller? G
                                                      Mh, soll ich versuchen mein Problem nochmals - feiner und säuberlicher - zu formulieren, oder - wofür ich vollstes Verständnis hätte - willst Du nimmer?

                                                      Beste Grüße
                                                      Viennamade

                                                      1. yo,

                                                        Mh, soll ich versuchen mein Problem nochmals - feiner und säuberlicher - zu formulieren, oder - wofür ich vollstes Verständnis hätte - willst Du nimmer?

                                                        also, die umgebung ist mir nun bekannt. ich bin nur deswegen verwirrt, weil du gesagt hast, alle abfragen funktionieren so wie sie sollen. aber wenn da noch eine fehlt, beschreib die abfrage mit worten.

                                                        Ilja

                                                        1. Hallo Ilja!

                                                          also, die umgebung ist mir nun bekannt. ich bin nur deswegen verwirrt, weil du gesagt hast, alle abfragen funktionieren so wie sie sollen. aber wenn da noch eine fehlt, beschreib die abfrage mit worten.

                                                          Yep! Das mache ich:

                                                          Ich verwende MySQL-Version 3.23.52-log.
                                                          Folgendes soll die 3 Tabellen darstellen. Ich kann deren Aufbau nimmer ändern.

                                                          -----------------------------      -------------------------------------------- -----------------
                                                          Tabelle_Bilder                     Tabelle_Bildertexte                          Tabelle_Sprachen
                                                          -----------------------------      -------------------------------------------- -----------------
                                                          PicNr    osname      pxhoehe       PicID     Bildnr Text                Sprache LangNr    Kuerzel
                                                          [PRIMARY]                          [PRIMARY]                                    [PRIMARY]
                                                          -----------------------------      -------------------------------------------- -----------------
                                                          1        Kuh.jpg     400           1         1      Das ist eine Kuh    1       1         DE
                                                          2        Hund.jpg    450           2         1      This is a cow       2       2         EN
                                                          3        Schwein.jpg 500           3         3      Das ist ein Schwein 1
                                                          4        Gans        600           4         4      This is a goose     2       v
                                                                                                                                          |
                                                          ^                                            v                          ^       |
                                                          |                                            |                          |       |
                                                          |                                            |                          |       |
                                                          +--------------------------------------------+                          +-------+

                                                          In der Tabelle_Bilder
                                                           gibts es pro Bild einen Datensatz.

                                                          In der Tabelle_Biltertexte kann es pro Bild bis zu 2 Datensätze geben. Diese beziehen sich auf ein Bild und eine Sprache. Es kann aber auch sein, daß nur ein Datensatz vorhanden ist (eben nur für eine Sprache), oder gar kein Datensatz.

                                                          An die Abfrage sollen 2 Variablen übergeben werden:
                                                           - Der osname, zB. 'Kuh.jpg'
                                                           - Die Sprache, zB. 'DE'

                                                          Zurückgeben soll die Abfrage in jedem Fall einen einzigen Datensatz der die Felder osname und Text enhaltet.
                                                          Dabei kann das Feld Text natürlich inhaltslos sein, wenn kein Bildertext vorhanden ist.

                                                          Ich schreibe jetzt absichtlich nichts über gute und schlechte Versuche ... und hoffe daß wir das jetzt hinbekommen :-)

                                                          Vielen Dank
                                                          Viennamade

                                                          1. yo,

                                                            SELECT ....
                                                            FROM tabelle_bilder AS b
                                                            LEFT JOIN tabelle_bildertexte AS bt ON (b.picnr = bt.bildnr)
                                                            LEFT JOIN tabelle_sprachen AS s ON (bt.sprache = s.langnr AND s.kuerzel='DE')
                                                            WHERE b.osname='Kuh.jpg'

                                                            oder kurzform

                                                            SELECT ....
                                                            FROM tabelle_bilder AS b
                                                            LEFT JOIN tabelle_bildertexte AS bt ON (b.picnr = bt.bildnr AND bt.sprache='1')
                                                            WHERE b.osname='Kuh.jpg'

                                                            beides sollte in jedem fall mindestens einen datensatz liefern.

                                                            Ilja

                                                            1. Hallo Ilja!

                                                              Leider.

                                                              SELECT ....
                                                              FROM tabelle_bilder AS b
                                                              LEFT JOIN tabelle_bildertexte AS bt ON (b.picnr = bt.bildnr)
                                                              LEFT JOIN tabelle_sprachen AS s ON (bt.sprache = s.langnr AND s.kuerzel='DE')
                                                              WHERE b.osname='Kuh.jpg'

                                                              oder kurzform

                                                              SELECT ....
                                                              FROM tabelle_bilder AS b
                                                              LEFT JOIN tabelle_bildertexte AS bt ON (b.picnr = bt.bildnr AND bt.sprache='1')
                                                              WHERE b.osname='Kuh.jpg'

                                                              beides sollte in jedem fall mindestens einen datensatz liefern.

                                                              Die Kurzform funktioniert perfekt. Die gewünschte Langform leider nicht.
                                                              -----------------------------      -------------------------------------------- -----------------
                                                              Tabelle_Bilder                     Tabelle_Bildertexte                          Tabelle_Sprachen
                                                              -----------------------------      -------------------------------------------- -----------------
                                                              PicNr    osname      pxhoehe       PicID     Bildnr Text                Sprache LangNr    Kuerzel
                                                              [PRIMARY]                          [PRIMARY]                                    [PRIMARY]
                                                              -----------------------------      -------------------------------------------- -----------------
                                                              1        Kuh.jpg     400           1         1      Das ist eine Kuh    1       1         DE
                                                              2        Hund.jpg    450           2         1      This is a cow       2       2         EN
                                                              3        Schwein.jpg 500           3         3      Das ist ein Schwein 1
                                                              4        Gans        600           4         4      This is a goose     2       v
                                                                                                                                              |
                                                              ^                                            v                          ^       |
                                                              |                                            |                          |       |
                                                              |                                            |                          |       |
                                                              +--------------------------------------------+                          +-------+

                                                              Beispiel ....
                                                              SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr,bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
                                                                FROM Bilder AS bi LEFT JOIN Bildertexte AS bitxt ON (bi.PicNr = bitxt.BildNr)
                                                                LEFT JOIN Sprachen AS s ON (bitxt.Sprache = s.LangNr AND s.Kuerzel='EN')
                                                                WHERE bi.osname = 'Schwein.jpg'
                                                              ... retourniert ...
                                                              Array
                                                              (
                                                                  [LangNr] =>
                                                                  [Kuerzel] =>
                                                                  [PicNr] => 214
                                                                  [BildNr] => 214
                                                                  [osname] => Schwein.jpg
                                                                  [pxhoehe] => 11
                                                                  [pxbreite] => 205
                                                                  [alttag] => Das ist ein Schwein   <- hier gehört eigentlich nichts her
                                                                  [title] => Das ist ein Schwein   <- hier gehört eigtenlich nichts her
                                                              )
                                                              ... also wird der deutsche Datensatz genommen, obwohl englisch abgefragt wird (s.Kuerzel='EN')!

                                                              Nach einigen Tests kann ich zusammenfassen:
                                                              Die Abfrage funktioniert nicht,
                                                               - wenn in Bildertexte nur ein Datensatz DE vorhanden und EN abgefragt wird (oder umgekehrt)
                                                              Die Abfrage funktioniert in allen anderen Fällen:
                                                               - wenn in Bildertexte gar kein Datensatz vorhanden ist.
                                                               - wenn eine Sprache abgefragt wird, zu der es in Bildertexte auch eine Entsprechung gibt.

                                                              Verstehe es nicht, am obigen Beispiel finde ich interessant, daß in  [LangNr] und [Kuerzel] gar nix drinnen steht.

                                                              Vielen Dank für Deine Bemühungen und Beste Grüße
                                                              Viennamade

                                                              1. yo,

                                                                Die Kurzform funktioniert perfekt. Die gewünschte Langform leider nicht.

                                                                funktionieren tun beide, beide liefern ergebnisse mit immer midestens einen datensatz. du musst dir vor augen halten, dass das problem an deinem datendesign liegt, sprich du hast einen deutschen oder englischen satz und hast eine weitere tabelle in der du die sprachkürzel lieferst. genau bei diesem problem kommen die ergebnisse zustande.

                                                                um das zu umgehen ist eine änderung deines daten-design notwendig.

                                                                a) du setzt die sprachtabelle vor den bildertexten, also die referenz zu den bilder ist in der sprachkürzel-tabelle. tabelle 2 und 3 tauschen quasi die positionen.

                                                                b) du nimmst das kürzel mit in die tabelle 2 rein, wie ich es schon mal vorgeschlagen habe.

                                                                ILja

                                                                1. Hallo Ilja,

                                                                  ich habe mich entschloßen Deinen Abfragestring "Kurzform" zu verwenden. Dafür muß ich in der Funktion eine zusätzliche, aber schlichte Miniabfrage auf die Sprachtabelle machen und das als Parameter übergebene Sprachkürzel in den Schlüssel umwandeln (also DE->1, EN->2, ...).

                                                                  Ich möchte mich recht herzlich für Deine "Spezialbehandlung" bedanken.

                                                                  Die Kurzform funktioniert perfekt. Die gewünschte Langform leider nicht.

                                                                  Obwohl ich es nicht mehr brauche ... b) verstehe ich, a) nicht:

                                                                  um das zu umgehen ist eine änderung deines daten-design notwendig.

                                                                  a) du setzt die sprachtabelle vor den bildertexten, also die referenz zu den bilder ist in der sprachkürzel-tabelle. tabelle 2 und 3 tauschen quasi die positionen.

                                                                  b) du nimmst das kürzel mit in die tabelle 2 rein, wie ich es schon mal vorgeschlagen habe.

                                                                  Also, Danke!
                                                                  Beste Grüße
                                                                  Viennamade

                                                                  1. yo,

                                                                    Obwohl ich es nicht mehr brauche ... b) verstehe ich, a) nicht:

                                                                    noch mal ein nachtrag zu lösung a)

                                                                    du hast die reihenfolge der tabelle bildertexte und sprachen verwechselt und genau das hat dann auch einfluss auf die abfragen.

                                                                    du hast:

                                                                    Bilder -> bildertexte -> sprachen

                                                                    richtig wäre aber:

                                                                    Bilder -> sprachen -> bildertexte

                                                                    und dann würde auch die langform der abfrage funktionieren. du kannst dir das bildlich vor augen halten. wenn du nur englische sätze haben willst, dann filterst du ja auch erst mal nach allen englischen sätzen. und von denen, die englisch sind, nimmst du dir den passenden raus. was du im moment hast ist, erst mal alle passenden sätze aller sprachen rauszunehmen und dann zu versuchen, nach den sprachen zu filtern.

                                                                    dieses vorgehen bringt aber wiederum probleme, wenn du immer mindestens einen datensatz haben willst, sprich mit einem left join arbeitest. das geht nur mit einem inner Join und dann bekommen wir auch nicht immer einen datensatz. änderst du nun aber die reihenfolge der beiden tabellen, so wie vorgeschlagen, dann geht auch der left joi sauber über die drei tabellen.

                                                                    Ilja

                                                                    1. Hallo!

                                                                      du hast:
                                                                      Bilder -> bildertexte -> sprachen
                                                                      richtig wäre aber:
                                                                      Bilder -> sprachen -> bildertexte

                                                                      Jezza! Jetzt habe ich es verstanden, warum ich bei meiner Reihenfolge mitunter keinen Datensatz bekomme. Die Tragweite für meine Anwendung habe ich noch nicht durchschaut ... mal sehen.

                                                                      Vielleicht eröffne ich ja demnächst einen Thread über Tabellenorganisation ;-)

                                                                      ... sollte ich mal auf ein selfhtml-Treffen kommen, dann bin ich mit einer Runde dran.
                                                                      Danke Ilja!
                                                                      Beste Grüße
                                                                      Viennamade

                                                                      1. yo,

                                                                        ... sollte ich mal auf ein selfhtml-Treffen kommen, dann bin ich mit einer Runde dran.

                                                                        also wenn das nächste treffen in berlin stattfindet, dann bin ich einem guten bier nicht abgeneigt ;-)

                                                                        Ilja

  3. Hi,

    Ich habe einen Abfragebedarf auf 3 Tabellen:

    und diese unübersichtlich beschriftet:

    tab_bilder                   tab_texte                  tab_sprachen

    Copyright

    id name                    bild_id   text    lang_id  id name

    -------------------------  -------------------------  ----------
    1 Kuh.jpg     false        1 Das ist eine Kuh      1  1 DE
    2 Hund.jpg    true         1 This is a cow         2  2 EN
    3 Schwein.jpg false        2 Das ist ein Hund      1
                               2 This is a dog         2
                               3 Das ist ein Schwein   1
                               3 This is a pig         2

    Eine Funktion erhält den Bildnamen und das Sprachkürzel, sagen wir Kuh.jpg und EN. Das Ergebnis soll sein false (keine Copyright) und "This is a cow". Nicht zu jedem Bild gibts Bildertexte in allen Sprachen.

    etwa so?:

    SELECT copyright, text
    FROM   tab_bilder, tab_texte, tab_sprachen
    WHERE  tab_bilder.name = 'kuh.jpg'
    AND    tab_sprachen.name = 'EN'
    AND    tab_bilder.id = tab_texte.bild_id
    AND    tab_texte.lang_id = tab_sprachen.id

    ungestested, aber meine Eitlkeit würde sich über eine Ergebnismeldung freuen.

    Gruß, Andreas

    --
    http://forum.andreas-lindig.de <img src="http://forum.andreas-lindig.de/bilder/logo.png" border="0" alt="">
    einfach mal testen und Meinung hinterlassen
    1. Hallo Andreas,

      Ich habe einen Abfragebedarf auf 3 Tabellen:
      und diese unübersichtlich beschriftet:

      aber dann doch verschönert:

      Ich verwende MySQL-Version 3.23.52-log.
      Folgendes soll die 3 Tabellen darstellen. Ich kann deren Aufbau nimmer ändern.

      -----------------------------      -------------------------------------------- -----------------
      Tabelle_Bilder                     Tabelle_Bildertexte                          Tabelle_Sprachen
      -----------------------------      -------------------------------------------- -----------------
      PicNr    osname      pxhoehe       PicID     Bildnr Text                Sprache LangNr    Kuerzel
      [PRIMARY]                          [PRIMARY]                                    [PRIMARY]
      -----------------------------      -------------------------------------------- -----------------
      1        Kuh.jpg     400           1         1      Das ist eine Kuh    1       1         DE
      2        Hund.jpg    450           2         1      This is a cow       2       2         EN
      3        Schwein.jpg 500           3         3      Das ist ein Schwein 1
      4        Gans        600           4         4      This is a goose     2       v
                                                                                      |
      ^                                            v                          ^       |
      |                                            |                          |       |
      |                                            |                          |       |
      +--------------------------------------------+                          +-------+

      Ich habe Deinen Abfrageentwurf auf die (hoffentlich) übersichtlichere Tabelle umgeschrieben:

      SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr,bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
        FROM Bilder AS bi,Bildertexte AS bitxt,Sprachen AS s
        WHERE
          bi.osname = 'Schwein.jpg'             <--- $a
          AND s.Kuerzel = 'DE'                  <--- $b
          AND bi.PicNr = bitxt.BildNr
          AND bitxt.Sprache = s.LangNr

      Leider mit gleichem Mißerfolg wie in manchen der vielen Postings zu diesem Thread.
      Das Ergebnis der Abfrage oben ist
      Array
      (
          [LangNr] => 1
          [Kuerzel] => DE
          [PicNr] => 214
          [BildNr] => 214
          [osname] => Schwein.jpg
          [pxhoehe] => 11
          [pxbreite] => 205
          [alttag] => Das ist ein Schwein
          [title] => Das ist ein Schwein
      )
      und das ist absolut korrekt. Ändere ich $b jedoch in 'EN', dann wird überhaupt kein Datensatz zurückgegeben. Korrekt wäre jedoch ein Datensatz. Die Felder aus Tabelle_Bilder müßten Werte enthalten (z.B. osname=Schwein.jpg ), die Felder aus Tabelle_Bildertexte müßten dann leer sein.

      Wenn Du das letzte Posting von Ilja liest (15. September 2004, 18:49), dann meint er - sicher zu recht - daß das Tabellendesign schlecht wäre. Zumindest der Punkt a) seiner dortigen Erklärungen sind mir unklar.

      Recht herzlichen Dank für Deine Bemühungen,
      Viennamade

      1. SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr,bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
          FROM Bilder AS bi,Bildertexte AS bitxt,Sprachen AS s
          WHERE
            bi.osname = 'Schwein.jpg'             <--- $a
            AND s.Kuerzel = 'DE'                  <--- $b
            AND bi.PicNr = bitxt.BildNr
            AND bitxt.Sprache = s.LangNr
        [...]
        Ändere ich $b jedoch in 'EN', dann wird überhaupt kein Datensatz zurückgegeben. Korrekt wäre jedoch ein Datensatz.

        Ich hatte übersehen, daß Du ja immer ein Ergebnis haben willst.
        Also:
        SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr,bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
        FROM Bilder AS bi LEFT JOIN Bildertexte AS bitxt, Sprachen AS s
        ON bi.PicNr = bitxt.BildNr
        WHERE
        bi.osname = 'Schwein
        AND
        (
            s.Kuerzel     = 'DE'
        AND bitxt.Sprache = s.LangNr
        )
        OR
        (
            bitxt.Sprache is NULL
        )

        Wenn Du das letzte Posting von Ilja liest (15. September 2004, 18:49), dann meint er - sicher zu recht - daß das Tabellendesign schlecht wäre. Zumindest der Punkt a) seiner dortigen Erklärungen sind mir unklar.

        Er meint, daß Du die Sprache holen sollst, bevor es in biler_text NULL-Werte gibt, aber dann müßtest Du in der Sprachtabelle für jedes Bild die möglichen Sprachen aufführen und außerdem bekommst Du dann schon dort NULL-Werte, weil schein.jpg nun mal dort nicht mir EN aufgeführt wäre. Halte ich im Ganzen nicht für gut, auch weil die Sprache nichts mit dem Bild zu tun hat und wegen der Redundanzen in der Sprachen-Tabelle.

        Gruß, Andreas

        --
        http://forum.andreas-lindig.de <img src="http://forum.andreas-lindig.de/bilder/logo.png" border="0" alt="">
        einfach mal testen und Meinung hinterlassen
        1. WHERE
          bi.osname = 'Schwein
          AND
          (
              s.Kuerzel     = 'DE'
          AND bitxt.Sprache = s.LangNr
          )
          OR
          (
              bitxt.Sprache is NULL
          )

          hehe, falsch geklammert:

          WHERE
          bi.osname = 'Schwein
          AND
          (
             (
                s.Kuerzel = 'DE'
                AND
                bitxt.Sprache = s.LangNr
             )
             OR
                bitxt.Sprache is NULL
          )

          ungetestet, dafür umso genialer, wenn es funktioniert ;-)

          Gruß, Andreas

          --
          http://forum.andreas-lindig.de <img src="http://forum.andreas-lindig.de/bilder/logo.png" border="0" alt="">
          einfach mal testen und Meinung hinterlassen
          1. Hallo Andreas!

            WHERE
            bi.osname = 'Schwein
            AND
            (
                s.Kuerzel     = 'DE'
            AND bitxt.Sprache = s.LangNr
            )
            OR
            (
                bitxt.Sprache is NULL
            )

            hehe, falsch geklammert:

            WHERE
            bi.osname = 'Schwein
            AND
            (
               (
                  s.Kuerzel = 'DE'
                  AND
                  bitxt.Sprache = s.LangNr
               )
               OR
                  bitxt.Sprache is NULL
            )

            ungetestet, dafür umso genialer, wenn es funktioniert ;-)

            Ich komme 'heute nacht' leider nicht dazu das zu testen. Eben habe ich es probiert mit

            SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr,bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title FROM Bilder AS bi LEFT JOIN Bildertexte AS bitxt, Sprachen AS s ON bi.PicNr=bitxt.BildNr WHERE bi.osname = 'x96.gif' AND ((s.Kuerzel= 'DE' AND bitxt.Sprache = s.LangNr) OR bitxt.Sprache is NULL)

            und knofle seit 15 Minuten an einem Syntaxfehler. Eigentlich schreibe ich das nur, um ein Verschwinden des Threads zu verhindern. Ich probiere Deinen String definitiv morgen (heute) Freitag ... also bis dann!

            Beste Danke & Grüße
            Viennamade

            1. Hallo Andreas!

              Ich tue jetzt eineinhalb Stunden mit Deinem Abfrageentwurf herum und bekomme immer einen Syntaxfehler, ich sehe aber keinen.

              Fehlernr: 1064

              Fehler: You have an error in your SQL syntax near ' Sprachen AS s ON bi.PicNr = bitxt.BildNr WHERE bi.osname = 'x96.gif' AND ((s.Ku' at line 1

              String:
              SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr, bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
                FROM Bilder AS bi LEFT JOIN Bildertexte AS bitxt, Sprachen AS s ON bi.PicNr = bitxt.BildNr
                WHERE bi.osname = 'x96.gif' AND ((s.Kuerzel= 'DE' AND bitxt.Sprache = s.LangNr) OR bitxt.Sprache IS NULL)

              Wenn Du das letzte Posting von Ilja liest (15. September 2004, 18:49), dann meint er - sicher zu recht - daß das Tabellendesign schlecht wäre. Zumindest der Punkt a) seiner dortigen Erklärungen sind mir unklar.

              Er meint, daß Du die Sprache holen sollst, bevor es in biler_text NULL-Werte gibt, aber dann müßtest Du in der Sprachtabelle für jedes Bild die möglichen Sprachen aufführen und außerdem bekommst Du dann schon dort NULL-Werte, weil schein.jpg nun mal dort nicht mir EN aufgeführt wäre. Halte ich im Ganzen nicht für gut, auch weil die Sprache nichts mit dem Bild zu tun hat und wegen der Redundanzen in der Sprachen-Tabelle.

              Gefallen tut mir Iljas Vorschlag auch nicht wirklich - aber wenns nicht anders geht... und logisch erscheint mir seine Begründung auch, aber das geht mir mit meinem Tabellenaufbau auch so - g.

              Mittlerweile habe ich die Funktion umgestellt. Zuerst wird die id des Sprachkürzels abgefragt, also 1 für DE, 2 für EN und mit dieser id wird dann in der "großen" Abfrage Bildertexte abgefragt. Also kein Join auf Sprachen. Also ich brauch keine Lösung mehr ...
              Andererseits würde es mich natürlich schon interessieren und jede Idee ausprobieren. Aber der Syntaxerror von oben ist mir ein Rätsel, vielleicht hängt es mit der MySQL-Version 3.23.52-log. zusammen ...

              Danke für Deine Bemühungen & Beste Grüße
              Viennamade

              1. Hallo ,

                Hallo Andreas!

                Ich tue jetzt eineinhalb Stunden mit Deinem Abfrageentwurf herum und bekomme immer einen Syntaxfehler, ich sehe aber keinen.

                Ich bin mir nicht sicher, ob man bei Verwendung von ON alle Tabellen joinen muß, also:

                tab_bilder LEFT JOIN tab_texte STRAIGHT JOIN/INNER JOIN tab_sprachen

                Gruß, Andreas

                --
                http://forum.andreas-lindig.de <img src="http://forum.andreas-lindig.de/bilder/logo.png" border="0" alt="">
                einfach mal testen und Meinung hinterlassen
                1. Hallo Andreas!

                  ... immer einen Syntaxfehler, ich sehe aber keinen.

                  Ich bin mir nicht sicher, ob man bei Verwendung von ON alle Tabellen joinen muß, also:
                  tab_bilder LEFT JOIN tab_texte STRAIGHT JOIN/INNER JOIN tab_sprachen

                  Ich habe probiert:
                  1 (ensprechend Deinem Posting -> 1064/Syntax):
                  SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr, bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
                    FROM Bilder AS bi LEFT JOIN Bildertexte AS bitxt STRAIGHT JOIN Sprachen AS s ON bi.PicNr = bitxt.BildNr
                    WHERE bi.osname = 'x96.gif' AND ((s.Kuerzel= 'DE' AND bitxt.Sprache = s.LangNr) OR bitxt.Sprache IS NULL)

                  2. (eine Variante aufgrund Deines Postings -> 1064/Syntax):
                  SELECT s.LangNr, s.Kuerzel, bi.PicNr, bitxt.BildNr, bi.osname, bi.pxhoehe, bi.pxbreite, bitxt.alttag, bitxt.title
                    FROM Bilder AS bi LEFT JOIN Bildertexte AS bitxt ON bi.PicNr = bitxt.BildNr STRAIGHT JOIN Sprachen AS s ON s.Kuerzel = bitxt.Sprache
                    WHERE bi.osname = 'x96.gif' AND ((s.Kuerzel= 'DE' AND bitxt.Sprache = s.LangNr) OR bitxt.Sprache IS NULL)

                  :-(  na eigentlich :-))))))))
                  kann nur mehr lachen g (mittlerweile ist es ja egal, habe ohnehin schon umgebaut)

                  Danke, Andreas
                  Viennamade