jank: SQL-Abfrage mit LIKE macht Probleme

hallo,

ich habe eine spalte code, die verschiedene werte enthält.
einige werte können mehrere codes haben, die durch ein komma getrennt wurden (bsp: zeile1).

zeile1: 15,17
zeile2: 15
zeile3: 1515

nun  möchte ich alle werte selektiert haben, die den code 15 enthalten. als ergebnis werden alle 3 zeile gebracht. das ist doch falsch!
ich will bei dieser abfrage nur zeile1+zeile2 selektiert haben. zeile3 hat doch mit 1515 einen eigenen anderen code.

mit folgender abfrage kommen die obigen ergebnisse.
was muss geändert werden, damit nur zeile1+zeile2 selektiert werden?

Abfrage: CODE LIKE "%15%"

vielen dank im voraus!!!

gruß jan

  1. Hello,

    was muss geändert werden, damit nur zeile1+zeile2 selektiert werden?

    eigentlich die Datenstruktur. Sie stößt jetzt schon sichtlich an ihre Grenzen. Du versuchst einen komplexen Sachverhalt zu einfach abzuspeichern.

    Wenn du dabei bleiben willst kann dir nur eine Regular Expression, Jonglieren mit String-Funktionen (Suche nach Komma o.ä.) oder eine Verknüpfung von Bedingungen mittels OR (Komma hinter 15, Komma vor 15, nichts hinter 15, nicht vor 15) helfen, was aber alles extrem suboptimal ist, da die Datenbank keinerlei Indizes verwenden kann.

    MfG
    Rouven

    --
    -------------------
    Buy when there's blood running in the street and sell when everyone is pounding at your door, clawing to own your equities  --  Wisdom on Wallstreet
    1. deine ideen kamen mir auch schon. aber ich dachte, es gibt eine bessere lösung. ich weiß, dass das nicht gerade optimal ist.

      aber ein abspeichern der einzelnen codes in einzelnen spalten ist doch auch müll, da ein wert 2 codes hat, der nächste hat 5 codes usw. - ist also alles dynamisch ...

      hast di einen vorschlag, wie man die datenstruktur ändern kann?

      Hello,

      was muss geändert werden, damit nur zeile1+zeile2 selektiert werden?
      eigentlich die Datenstruktur. Sie stößt jetzt schon sichtlich an ihre Grenzen. Du versuchst einen komplexen Sachverhalt zu einfach abzuspeichern.

      Wenn du dabei bleiben willst kann dir nur eine Regular Expression, Jonglieren mit String-Funktionen (Suche nach Komma o.ä.) oder eine Verknüpfung von Bedingungen mittels OR (Komma hinter 15, Komma vor 15, nichts hinter 15, nicht vor 15) helfen, was aber alles extrem suboptimal ist, da die Datenbank keinerlei Indizes verwenden kann.

      MfG
      Rouven

      1. Mahlzeit,

        hast di einen vorschlag, wie man die datenstruktur ändern kann?

        Eine Kreuztabelle verwenden.

        Achja - und TOFU vermeiden, wenn's geht ...

        MfG,
        EKKi

        --
        sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
        1. Hello,

          Eine Kreuztabelle verwenden.

          ...was soviel heißt wie:
          Code
          -----------
          15 | wert 1
          16 | wert 2
          ...

          Objekt
          ------------
          1  | obj1
          2  | obj2

          CodeObject
          ------------
          1  | 15
          1  | 16
          2  | 16

          MfG
          Rouven

          --
          -------------------
          He is entertaining both out of the car and in the car because if you tell him that a corner is almost flat then he is the guy who is going to try to take it flat even if it means shunting it the other side of it, he will come with the data and say 'hey, I may have crashed and destroyed the car, but I was flat-out'. That is an interesting quality that he has!  --  Team Member on Jacques Villeneuve
          1. Hi,

            ja, das klingt schwer nach m:n-Relation, alles andere waere unsauber.

            Tja, aber unsauber is manchmal leichter, und gar ist sowas haesslich unnormalisiertes auch mal schneller (das muss hier nun wirklich nicht der Fall sein), daher mein Vorschlag:

            Das mit LIKE "%15%" wuerde funktionieren, wenn du abfragst

            LIKE "%,15,%"

            und deine Spalteninhalte so aussehen:

            [...]
            ,13,14,15,
            ,1315,1415,1515,
            ,15,151,515,
            [...]

            Zumindest behaupt ich das mal so (is ja schon spaet).

            Trotzdem, n:m is sauberer. Hier mag das noch gehen, aber wehe in 2 Jahren, wenn deine Applikation mal so richtig gewachsen ist, und jemand will alle Spalten in denen der Code '15' UND '16' vorkommt, oder der Code mit einem Code in einer anderen Tabelle uebereinstimmen muss.

            Solche Sachen solltest du dir davor GRUENDLICH ueberlegen.

      2. Hi,

        aber ich dachte, es gibt eine bessere lösung.

        Die bessere bzw beste Lösung ist, ein für den Verwendungszweck geeignetes Datenmodell zu haben.

        "Kreuztabelle" ist nicht ganz der passende Name, es handelt sich - wie von Rouven skizziert - um eine m:n Relationstabelle.

        Gruss, Frank

  2. Hello,

    zeile1: 15,17
    zeile2: 15
    zeile3: 1515

    Welches Datenbanksystem verwendest Du?

    Bei MySQL gibt es dafür die Funktion find_in_set()
    http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_find-in-set

    Beipiel
    liste is vom Typ VarChar und enthält die Werte so gelistet, wie Du es aufgeführt hast
    Das Komma ist hier VORGESCHRIEBEN als Trennzeichen.

    select id_zeit, liste from zeit where find_in_set('200',liste);

    funktioniert genau passend für Dein Beispiel

    Harzliche Grüße vom Berg
    http://bergpost.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)