MySQL: Platzhalter ablegen

Ich möchte einen Platzhalter in der Spalte ablegen. Also zum Beispiel:
"foo/%/bar" % => Platzhalter

Hi,

wieso machst Du das nicht einfach?

Code:
SELECT * FROM test;
++++++++++
foo/%/bar

SELECT * FROM test
WHERE 'foo/wuff/bar' LIKE field1
+++++++++
foo/%/bar
bekomme in beiden Fällen den Treffer.
Ob Du das nun mit URLs machst oder mit was anderem ist gehopst wie gesprungen.

Ist das Problem also, dass es bei dir so *nicht* funktioniert?

Grüße,
MArc
 
Na klar funktioniert es, genauso habe ich es doch in meinem ersten Post beschrieben ;)

Nur liefert dass dann auch Ergebnisse wie:

foo/%

aber nur

foo/%/bar

soll getroffen werden.

Ist für Like ja auch typisch ist. Daher die Frage nach REGEXP.


Mein erster Beitrag beschreibt das Problem doch eigentlich recht deutlich. ;) Nichts anderes ist gefragt, trotzdem danke.
 
Zuletzt bearbeitet:
Hey,
ok jetzt wird's klarer.

Hast du mal versuch einen "globales" schlußzeichen zu definieren`?
Zum Beispiel, dass du hingehst und sagst jede Spalte plus einem $
Bei den Strings "von außen" hängst du dann natürlich ebenfalls ein $ ans ende an
und schon haste dasProblem mit ungewollten Übereinstimmungen gelöst, oder?

So hatte ich das damals auch gelöst, als ich in der Datenbank definiert hatte, welche Links quasi
"gültig" inkl. wildcard (in dem fall % und _ ) sind und so dann verglichen - hatte ziemlich gut funktioniert.

Grüße,
MArc
 
Hast du mal versuch einen "globales" schlußzeichen zu definieren`?
Zum Beispiel, dass du hingehst und sagst jede Spalte plus einem $
Bei den Strings "von außen" hängst du dann natürlich ebenfalls ein $ ans ende an
und schon haste dasProblem mit ungewollten Übereinstimmungen gelöst, oder?

Ja, genau diesen Gedankengang hatte ich auch und habe es auch versucht nur bin ich leider nicht zu einer Lösung gekommen.
 
Jetzt wäre ein guter Zeitpunkt, um uns zu sagen, an welcher stelle die Lösung hakt.
Welche art von URLs können in deinem Fall DENN verglichen werden und geben eine ungewolltest Resultat zurück ?

Achja, Du kannst das LIKE natürlich durch REGEXP ersetzen, nur
müssen dann natürlich die expr. auf regexp angepasst werden.
Dann kannst wirklich genau definieren, wie wo welchee URL gültig ist ohne ausnahmen und einengung von LIKE.

Code:
SELECT * FROM foo;
++++++++
^foo/.*/bar$

SELECT * FROM `test` WHERE 'foo/sd/bar' REGEXP field1
++++++++
^foo/.*/bar$

SELECT * FROM `test` WHERE 'foo/sd' REGEXP field1
=> kein treffer

Ich denke das sollte die Lösung sein.

Grüße,
MArc
 
Jetzt wäre ein guter Zeitpunkt, um uns zu sagen, an welcher stelle die Lösung hakt.
Habe ich bereits im ersten Post gemacht ;) Wenn der Platzhalter sich mitten in einem String befindet :)

Welche art von URLs können in deinem Fall DENN verglichen werden und geben eine ungewolltest Resultat zurück ?
Das ist ja nicht wirklich wichtig oder? Ich möchte Spalten treffen wie im ersten Beispiel erwähnt. Es gibt also Strings mit Platzhaltern mitten im String, wie genau die aussehen wäre jetzt hier einfach zu viel, aber wie gesagt ist es auch unwichtig wie genau sie aussehen, wichtig ist nur der Platzhalter befindet sich mitten im String. :)

Achja, Du kannst das LIKE natürlich durch REGEXP ersetzen, nur
müssen dann natürlich die expr. auf regexp angepasst werden.
Dann kannst wirklich genau definieren, wie wo welchee URL gültig ist ohne ausnahmen und einengung von LIKE.

Code:
SELECT * FROM foo;
++++++++
^foo/.*/bar$

SELECT * FROM `test` WHERE 'foo/sd/bar' REGEXP field1
++++++++
^foo/.*/bar$

SELECT * FROM `test` WHERE 'foo/sd' REGEXP field1
=> kein treffer
Ich denke das sollte die Lösung sein.

Ja, nur wollte ich eigentlich keine regulären Ausdrücke in den Spalten ablegen sondern nur ein Zeichen als Platzhalter (bzw. gibt es die Datensätze in der Form eben schon), hm..

Mich hat jemand darauf hingewiesen das Drupal etwas ähnliches für das Routing nutzt und ich habe mal einen schnellen Blick darauf geworfen und dort scheint es in der Tat so zu laufen, es wird auch ein % als Platzhalter abgelegt und auch teilweise mit in einem String. Nur blicke ich durch die Architektur von Drupal ansonsten nicht durch um mich zu den Queries vorzuschlagen. :(

Sollte sonst noch jemand eine Idee haben, die es ermöglicht wirklich nur mit einem einzigen Platzhalter (%) zu arbeiten wäre ich sehr dankbar. :)


Ist doch klar wo das Problem liegt oder? Nur nochmal zur Sicherheit: Bei der LIKE Abfrage aus meinem ersten Beispiel wird
natürlich ab dem Platzhalter alles aktzeptiert. Sieht der Platzhalter so aus:

"foo/%/bar"

dann erzeugen

foo/xyz
foo/bar
foo/yoo/boo

alle Treffer, aber nur

foo/xyz/bar oder foo/boo/bar usw. sollten Treffer erzeugen. Eben wie in MArcs REGEXP Beispiel.
 
Zuletzt bearbeitet:
Ja, nur wollte ich eigentlich keine regulären Ausdrücke in den Spalten ablegen sondern nur ein Zeichen als Platzhalter (bzw. gibt es die Datensätze in der Form eben schon), hm..

Ach, da drückt der Schuh.
Also, wenn ich das nun richtig gerafft habe, dann hast Du in deinem Fall wohl nur 2 Möglichkeiten:
*) du änderst einfach die %/_-Platzhalter mit regexp aus und hast die volle Macht
oder
*) du verwendest die Variante mit dem Schlußzeichen und musst ggf abstriche machen.

Wenn Du mit der Überlegung kämpfst, nach dem WHERE als Bedinung auf *beiden* Seiten unterschiedlich Vergleichstechniken zu nutzen, wird das nicht funktionieren.
Zum einen Technisch nicht möglich und zum anderen sind die Daten eben
in, ich sag mal, LiKE-Form gespeichert und die hat eben Löcher, die man nicht
mit regexp stopfen kann (außer du detailierst die wildcard mit einem skript o.ä. - wie schon geschrieben)

Edit: Zu deinem Edit:
Das Problem kannst Du aber mit dem ersten Lösungsansatz(ein zeichen dranhängen) in Griff bekommen.

Grüße und nacht,
MArc
 
Zuletzt bearbeitet:
Edit: Zu deinem Edit:
Das Problem kannst Du aber mit dem ersten Lösungsansatz(ein zeichen dranhängen) in Griff bekommen.

Hey MArc. Ja? Das wäre super, nur weiß ich leider nicht genau was du meinst? Du meinst ich kann auch für die LIKE Variante ein Schlußzeichen bestimmen? Muss ich dazu auch die Datensätze ändern? Ich weiß leider nicht wie das möglich ist...
 
Morgen,

also:
Zu deinem Edit nochmal - gestern hatte wohl mein Hirn bissle Probleme.

Wir haben folgende Strings, die verglichen werden:
Code:
foo/xyz
foo/bar
foo/yoo/boo

Wir haben folgenden Inhalt in meiner Tabelle:
SQL:
SELECT * FROM test;
++++++++++++
foo/%/bar

Folgend sind meiner Ergebnisse:
Code:
SELECT * FROM `test` WHERE 'foo/asd' LIKE field1 => kein Treffer
SELECT * FROM `test` WHERE 'foo/bar' LIKE field1 => kein Treffer
SELECT * FROM `test` WHERE 'foo/yoo/boo' LIKE field1 => kein Treffer
SELECT * FROM `test` WHERE 'foo/blaa/bar' LIKE field1 => Treffer
Also, wie man erkennt, bekomme ich nur Treffer, wenn am Anfang 'foo/' und
am Ende '/bar' steht.

Wenn du aber in der Tabelle ´test´ ein Eintrag "foo/%" hast, dann ist klar, dass
dieser *immer* getroffen wird - das löst du auch nicht mit regexp - denn
das ist genauso ein eindeutiger Treffer wie einer, der ein bisschen, ich sag mal, "genauer" ist.

Noch etwas als Hinweis
SQL:
SELECT * FROM `test` WHERE 'foo/yoo/bar' REGEXP CONCAT( '^',REPLACE(field1,'%', '.*'), '$')
Sowas geht natürlich auch - also musste deine Daten garnicht umschreiben, um
REGEXP zu benutzen, auch wenn das im zweifelsfall langsam ist (ich schätz bei > 100.000 einträge wirste es merken)
Ob das nun irgendwie zur Lösung deines Problems hilft, kann ich nicht beurteilen.
Weil, wie schon geschriebe, die Beispielstring, die du oben genannt hast, greifen bei mir nicht und so bekomme ich nur den Treffer, den ich will - außer, ja außer natürlich
Du hast in der Tabelle ein Wert, der als letztes Zeichen ein "%" hat - aber ist logisch.

Grüße und viel Glück,
MArc
 
Zuletzt bearbeitet von einem Moderator:
Also, wie man erkennt, bekomme ich nur Treffer, wenn am Anfang 'foo/' und
am Ende '/bar' steht.

Weil du eben nur den einen Datensatz in der Tabelle hast ;) Wie gesagt ich habe aber auch Datensätze die sich ähneln und am ende den Platzhalter haben, zum Beispiel also:

"foo/%"
"foo/%/bar"


Wenn du aber in der Tabelle ´test´ ein Eintrag "foo/%" hast, dann ist klar, dass
dieser *immer* getroffen wird - das löst du auch nicht mit regexp - denn
das ist genauso ein eindeutiger Treffer wie einer, der ein bisschen, ich sag mal, "genauer" ist.

Siehe oben. Aber mit REGEXP kann man es schon lösen, nur eben nicht wenn die Daten wie momentan mit einem % als Platzhalter vorliegen.

Noch etwas als Hinweis
sql Code:
SELECT * FROM `test` WHERE 'foo/yoo/bar' REGEXP CONCAT( '^',REPLACE(field1,'%', '.*'), '$')



Sowas geht natürlich auch - also musste deine Daten garnicht umschreiben, um
REGEXP zu benutzen, auch wenn das im zweifelsfall langsam ist (ich schätz bei > 100.000 einträge wirste es merken)
Ob das nun irgendwie zur Lösung deines Problems hilft, kann ich nicht beurteilen.

Ja, darüber habe ich auch schon nachgedacht und wahrscheinlich bleibt mir nichts anderes übrig :(
 
Zurück