Maik W. aus E.: mySQL: JOIN mit LIKE

Tach zusammen,

fogendes Problem:

Die Verknüpfung zweier Tabellen läuft über die Referenz-Spalte extended_ref der Tabelle br_basisdaten auf die Tabelle br_rec_extended

  
  
SELECT bas.basisdaten_id, ex.cell_ref  
FROM br_basisdaten bas, br_rec_extended ex  
WHERE 1  
AND bas.extended_ref=ex.extended_id  
AND ex.cell_ref='$cell'  

Soweit so gut. In der neuen Version (nicht meine Tabelle) sind nun Referenzen auf mehrere Werte der br_rec_extended, durch Kommata getrennt, hinterlegt, so daß ein

  
  
SELECT bas.basisdaten_id, ex.cell_ref  
FROM br_basisdaten bas, br_rec_extended ex  
WHERE 1  
AND bas.extended_ref like '%,ex.extended_id,%'  
AND ex.cell_ref='$cell'  

funktionieren könnte. Das macht es aber nicht, mySQL gibt keine Fehlermeldung, aber auch keine Ergebnisse aus.

Meine Versuche mit JOIN

  
SELECT bas.basisdaten_id, ex.cell_ref  
FROM br_basisdaten bas, br_rec_extended ex  
INNER JOIN br_basisdaten ON bas.extended_ref = ex.extended_id  
WHERE ex.cell_ref = '$cell'  

brachten auch keine Ergebnisse, dauerten aber viel länger...

Hat jemand eine Idee, wie man das zusammenbringen kann?

Danke und
http://www.gruss-aus-essen.de

Maik

  1. Hallo Maik,

    Soweit so gut. In der neuen Version (nicht meine Tabelle) sind nun Referenzen auf mehrere Werte der br_rec_extended, durch Kommata getrennt, hinterlegt,

    soweit, so schlecht. Mehr dazu unten.

    so daß ein

    SELECT bas.basisdaten_id, ex.cell_ref
    FROM br_basisdaten bas, br_rec_extended ex
    WHERE 1
    AND bas.extended_ref like '%,ex.extended_id,%'

    Was beabsichtigst Du da genau?
    ex.extended_id wird hier als Zeichenkette genommen, nicht etwa durch einen Feldinhalt ersetzt. SQL ist kein Shellskript, Perl, PHP, ... mit Variablensubstitution.
    Und selbst wenn es gehen würde, betrachte die Spezialfälle "Erster Eintrag" und "Letzter Eintrag".

    funktionieren könnte. Das macht es aber nicht, mySQL gibt keine Fehlermeldung, aber auch keine Ergebnisse aus.

    Es dürfte keinen Eintrag mit genau diesem Text

    <irgendwas>,ex.extended_id,<irgendwas anderes>

    geben. Das ist mehr als wahrscheinlich.

    Meine Versuche mit JOIN

    [code lang=sql]
    SELECT bas.basisdaten_id, ex.cell_ref
    FROM br_basisdaten bas, br_rec_extended ex
    INNER JOIN br_basisdaten ON bas.extended_ref = ex.extended_id
    WHERE ex.cell_ref = '$cell'

    
    >   
    > brachten auch keine Ergebnisse, dauerten aber viel länger...  
      
    Kein Wunder. Du hast da ein Kreuzprodukt drin. Beinahe wäre es das gleiche wie Deine erste Abfrage.  
      
    
    > Hat jemand eine Idee, wie man das zusammenbringen kann?  
      
    Bitte lies [meine Ausführungen zu JOIN](/archiv/2005/8/t113001/#m716818). Dann schnappe Dir die Person, die die neue Version verbrochen hat. Sowas gehört sich nicht.  
      
    
    > Soweit so gut. In der neuen Version (nicht meine Tabelle) sind nun Referenzen auf mehrere Werte der br\_rec\_extended, durch Kommata getrennt, hinterlegt  
      
    Das ist ein elementarer Verstoß gegen die Normalisierungsprinzipien bei relationalen Datenbanken, [erste Normalform](http://www.sql-und-xml.de/sql-tutorial/erste-normalform-datentypen.html):  
      
        "Alle Daten liegen atomar vor"  
      
    Mir fällt nichts ein, was das Abweichen von diesem simplen und einfachen Grundprinzip wünschenswert erscheinen lässt. Beseitige diesen nicht wünschenswerten Zustand und Dein Problem erledigt sich von selbst.  
      
      
    Freundliche Grüße  
      
    Vinzenz
    
    1. Tach auch Vinzenz,

      Soweit so gut. In der neuen Version (nicht meine Tabelle) sind nun Referenzen auf mehrere Werte der br_rec_extended, durch Kommata getrennt, hinterlegt,

      soweit, so schlecht. Mehr dazu unten.

      so daß ein

      SELECT bas.basisdaten_id, ex.cell_ref
      FROM br_basisdaten bas, br_rec_extended ex
      WHERE 1
      AND bas.extended_ref like '%,ex.extended_id,%'

      Was beabsichtigst Du da genau?
      ex.extended_id wird hier als Zeichenkette genommen, nicht etwa durch einen Feldinhalt ersetzt. SQL ist kein Shellskript, Perl, PHP, ... mit Variablensubstitution.

      Schade. Ich zögere vor der Arbeit der Normalisierung (also der br_extended_ref eine spalte "br_basisdaten_ref" mitzugeben und sie somit zur klassischen Kreuztabelle zu machen) und hoffte hintenrum durchs Knie drumrum zu kommen 8>)

      Und selbst wenn es gehen würde, betrachte die Spezialfälle "Erster Eintrag" und "Letzter Eintrag".

      Das lies sich abfangen, über concat habe ich jedem Wert vorne und hinten ein ',' mitgegeben.

      Es dürfte keinen Eintrag mit genau diesem Text

      <irgendwas>,ex.extended_id,<irgendwas anderes>

      geben. Das ist mehr als wahrscheinlich.

      Allerding. Ich war so blauäugig, auf <irgendwas>,Wert der ex.extended_id,<irgendwas anderes>
      zu hoffen.

      Meine Versuche mit JOIN

      [code lang=sql]
      SELECT bas.basisdaten_id, ex.cell_ref
      FROM br_basisdaten bas, br_rec_extended ex
      INNER JOIN br_basisdaten ON bas.extended_ref = ex.extended_id
      WHERE ex.cell_ref = '$cell'

      
      > >   
      > > brachten auch keine Ergebnisse, dauerten aber viel länger...  
      >   
      > Kein Wunder. Du hast da ein Kreuzprodukt drin. Beinahe wäre es das gleiche wie Deine erste Abfrage.  
      >   
      > > Hat jemand eine Idee, wie man das zusammenbringen kann?  
      >   
      > Bitte lies [meine Ausführungen zu JOIN](/archiv/2005/8/t113001/#m716818).  
      
      Hatte ich. Deswegen auch meine zugegeben -etwas dilletantischen-Versuche mit Join. Ich fand keine Syntax mit Like und hoffte auf einen Tip á la IN oder so...  
      Dann schnappe Dir die Person, die die neue Version verbrochen hat. Sowas gehört sich nicht.  
        
      Ich weiß, hoffte aber...siehe oben  
      
      >   
      > > Soweit so gut. In der neuen Version (nicht meine Tabelle) sind nun Referenzen auf mehrere Werte der br\_rec\_extended, durch Kommata getrennt, hinterlegt  
      >   
      > Das ist ein elementarer Verstoß gegen die Normalisierungsprinzipien bei relationalen Datenbanken, [erste Normalform](http://www.sql-und-xml.de/sql-tutorial/erste-normalform-datentypen.html):  
      >   
      >     "Alle Daten liegen atomar vor"  
      >   
      > Mir fällt nichts ein, was das Abweichen von diesem simplen und einfachen Grundprinzip wünschenswert erscheinen lässt. Beseitige diesen nicht wünschenswerten Zustand und Dein Problem erledigt sich von selbst.  
        
      O.K. muß ich wohl, wenn kein Weg daran vorbeiführt  
        
      Danke und  
      <http://www.gruss-aus-essen.de>  
        
      Maik
      
    2. yo,

      Das ist ein elementarer Verstoß gegen die Normalisierungsprinzipien bei relationalen Datenbanken, erste Normalform:

      der Link, bzw. vielmehr der inhalt dort ist auch nicht das gelbe vom ei. zum einen wird wieder einmal der begriff relation falsch verwendet und zum anderen wird leider nicht deutlich wodurch sie atomarität kennzeichnet. nachname und vorname können nämlich sehr wohl in einer spalte geführt werden und würden trotzdem die atomarität erfüllen.

      was das datendesign betrifft, so gebe ich dir recht, dass ist sehr ungünstig und wer immer das "verbrochen" hat, sollte die suppe selbst auslöffeln. immer nur dann schwierig, wenn es ein vorgesetzter oder geldgeber ist.

      sollte derjenige sich quer stellen, so sehe ich eine möglichkeit, es über eine hilfstabelle zu lösen, in der erst einmal alle id in einer spalten einzeln "gesammelt" werden. das ist aber mehr eine bauchlösung als dass ich mir konkrete gedanken gemacht hätte, wie das aussehen könnte.

      Ilja

  2. Hi Maik,

    Kritik zum etwas verkorksten DB-Design hat Vinzenz ja schon abgelassen ... Aber wenn du das nachbessern wirklich scheust, schau dir doch mal MySQL-Stringfunktion FIND_IN_SET() an.
    Anders, als der Name vermuten liesse, läßt diese sich nämlich nicht nur auf den Datentyp SET anwenden, sondern auch auf String-Datentypen, die einen Inhalt in der Form 'a,b,c,d' haben.

    Allerdings gibt diese Funktion lediglich die Nummer der Position zurück, an der der gesuchte Wert in der Zeichenkette steht.
    Wenn du also den Wert selber nicht brauchst - und danach sieht mir dein Beispiel aus, denn den gesuchten Wert hast du ja bereits als Eingabedatum vorliegen - dann dürfte die Abfrage auf Ergebnis FIND_IN_SET(...) ungleich 0 ausreichend sein.

    Allerdings schließe ich mich Vinzenz in sofern an, dass eine Normalisierung sicherlich der bessere Weg wäre.
    Wer kann jetzt schon absehen, welche Probleme dir die derzeitige, suboptimale Struktur bei zukünftigen Aufgaben noch bereiten wird ...?

    Gruß nach Essen,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }