Umgekehrte Sortierung mit ORDER BY
Stefan Einspender
- datenbank
Hallo ForumsleserInnen,
gibt es eine Möglichkeit, dass ich bei ORDER BY die Daten so sortiere, dass
die Strings von hinten an ausgelesen werden?
Jetzt habe ich:
abcd
dasdf
aare
Mein Ziel ist, dass intern die Strings "umgedreht" werden, also 'dcba',
'fdsad' und 'eraa' und danach die Sortierung stattfindet.
abcd
aare
dasdf
Gibt es da eine Möglichkeit, dass ich diese Sache in einem SELECT unter-
bringen kann? Verwendet wird MySQL 5.1 als Datenbank.
Viele Grüße,
Stefan
Hallo Stefan,
gibt es eine Möglichkeit, dass ich bei ORDER BY die Daten so sortiere, dass
die Strings von hinten an ausgelesen werden?
ja, nur nicht effizient.
abcd
dasdf
aareMein Ziel ist, dass intern die Strings "umgedreht" werden, also 'dcba',
'fdsad' und 'eraa' und danach die Sortierung stattfindet.abcd
aare
dasdfGibt es da eine Möglichkeit, dass ich diese Sache in einem SELECT unter-
bringen kann? Verwendet wird MySQL 5.1 als Datenbank.
Verwende die Funktion REVERSE():
SELECT
spalte
FROM
tabelle
ORDER BY
[link:http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_reverse@title=REVERSE](spalte)
Freundliche Grüße
Vinzenz
Hallo Vinzenz,
Verwende die Funktion REVERSE():
SELECT
spalte
FROM
tabelle
ORDER BY
link:http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_reverse@title=REVERSE
einwandfrei, hatte schon die Befürchtung, ich müßte dafür noch eine Spalte
hinzufügen. Die Funktion bringt genau den von mir gewünschten Effekt, danke.
Ausnahmsweise will ich da mal noch eine kleine (?) Frage dranhängen. Also
ich habe in der Tabelle eigentlich jeden Menge Hostnamen stehen, so z.Bsp.
p58E68.dip0.t-ipconnect.de
pD30B8.dip0.t-ipconnect.de
p5B1C8.dip0.t-ipconnect.de
Und in einer anderen Tabelle stehen für die verschiedenen Provider (bzw.
die Backbone-Provider) die typischen Endungen, hier wäre es dann
'.dip0.t-ipconnect.de'. Wie kann ich jetzt nur die Hostnamen ausgeben,
die nicht schon als Provider eingetragen sind?
... WHERE remote\_host NOT LIKE '%(SELECT hostendung FROM provider)' ...
Ganz so einfach geht es ja leider nicht :-(
Die Hostendungen können unterschiedlich lang sein und ich kann quasi nur
vergleichen, ob in provider (Spalte hostendung) der remote\_host vorkommt.
Viele Grüße,
Stefan
Hallo Stefan,
Wie kann ich jetzt nur die Hostnamen ausgeben, die nicht schon als Provider eingetragen sind?
... WHERE remote_host NOT LIKE '%(SELECT hostendung FROM provider)' ...
Ganz so einfach geht es ja leider nicht :-(
Die Hostendungen können unterschiedlich lang sein und ich kann quasi nur
vergleichen, ob in provider (Spalte hostendung) der remote_host vorkommt.
hast Du es schon einmal REGEXP versucht?
Freundliche Grüße
Vinzenz
Hallo Vinzenz,
hast Du es schon einmal REGEXP versucht?
ja, aber leider erfolglos. Also direkt auf eine bestimmten Endung, wie
remote_host NOT REGEXP '^.*\.dip0\.t-ipconnect\.de$'
funktioniert es, aber wenn ich das Subselect reinbringe, dann leider nicht
mehr oder ich weiß die korrekte Syntax nicht :-(
remote_host NOT REGEXP '^.*(SELECT hostendung FROM provider)$'
Viele Grüße,
Stefan
Hi,
ja, aber leider erfolglos. Also direkt auf eine bestimmten Endung, wie
remote_host NOT REGEXP '^.*\.dip0\.t-ipconnect\.de$'
funktioniert es, aber wenn ich das Subselect reinbringe, dann leider nicht
mehr oder ich weiß die korrekte Syntax nicht :-(remote_host NOT REGEXP '^.*(SELECT hostendung FROM provider)$'
Da ist ja ueberhaupt kein Subselect drin :-) - lediglich etwas, was zufaelligerweise wie eine SELECT-Anweisung aussieht, als Bestandteil eines Textliterals.
'^.*', Ergebnis-von-Select und '$' muesste also erst mal zusammengebracht werden - bspw., in dem man die beiden Zeichenketten *ins* SELECT-Statement verlagert, und dort mittels CONCAT() mit dem Spalteninhalt kombiniert (um dessen RegEx-gerechtes Escaping man sich dann an der Stelle wohl auch noch kuemmern muesste).
Aber, um's gleich zu sagen, wird auch das vermutlich nicht funktionieren, weil die Subquery mehr als einen Ergebnisdatensatz zurueckliefert, und MySQL das beim Vergleich mittels NOT REGEXP m.W. nicht akzeptieren wird.
Wesentlich einfacher - und wohl auch performanter - koenntest du das haben, wenn du das Datum 'p58E68.dip0.t-ipconnect.de' in zwei Datuemer aufsplittest - Teil-vor-Hostname und Hostname - und in zwei einzelnen Spalten unterbringst.
Waere das eine Option, oder spricht da was anderes ernsthaft dagegen?
MfG ChrisB
Hallo ChrisB,
Wesentlich einfacher - und wohl auch performanter - koenntest du das haben, wenn du das Datum 'p58E68.dip0.t-ipconnect.de' in zwei Datuemer aufsplittest - Teil-vor-Hostname und Hostname - und in zwei einzelnen Spalten unterbringst.
Waere das eine Option, oder spricht da was anderes ernsthaft dagegen?
ja und zwar gibt es Provider, bei denen ist der Hostname nur example.org und
bei anderen ist es 1Cust44.tnt5.fft4.deu.da.example.net - die kann ich dann
technisch nicht trennen. Ab und an prüfe ich manuell, ob ich diese Einträge
einem Provider zuordne oder nicht. Könnte dann, beim zweiten Hostnamen,
'.example.net' oder auch '.tnt5.fft4.deu.da.example.net' werden ...
Viele Grüße,
Stefan
Hi,
ja und zwar gibt es Provider, bei denen ist der Hostname nur example.org und
bei anderen ist es 1Cust44.tnt5.fft4.deu.da.example.net - die kann ich dann
technisch nicht trennen.
Hm, wenn diese Trennung nicht moeglich ist - wie befuellst du denn dann ueberhaupt deine provider-Tabelle?
Ab und an prüfe ich manuell, ob ich diese Einträge
einem Provider zuordne oder nicht. Könnte dann, beim zweiten Hostnamen,
'.example.net' oder auch '.tnt5.fft4.deu.da.example.net' werden ...
Aha, also ziemliche Willkuer(?) :-)
Nach welchem System entscheidest du dich denn jetzt bei diesem Beispiel fuer das eine oder andere?
Um deine gewuenschte Ergebnismenge zu bekommen, muesstest du schon ziemlich wild mit Stringfunktionen hantieren ...
Wenn du REVERSE() mit INSTR() kombinierst, koenntest du wohl zumindest schon mal feststellen, ob ein remotehost auf eine deiner hostendungen endet.
Aber das mit der Subquery zu kombinieren, dazu sehe ich gerade immer noch keine Moeglichkeit - wird wohl eher auf einen JOIN hinauslaufen, wuerde ich sagen.
MfG ChrisB
Hallo,
Hm, wenn diese Trennung nicht moeglich ist - wie befuellst du denn dann ueberhaupt deine provider-Tabelle?
manuell, d.h. nach persönlichem Ermessen ;-)
Ab und an prüfe ich manuell, ob ich diese Einträge
einem Provider zuordne oder nicht. Könnte dann, beim zweiten Hostnamen,
'.example.net' oder auch '.tnt5.fft4.deu.da.example.net' werden ...Aha, also ziemliche Willkuer(?) :-)
Nach welchem System entscheidest du dich denn jetzt bei diesem Beispiel fuer das eine oder andere?
Wenn ich eine ausreichend große Anzahl (?) von Hostnamen nach diesem
Muster habe, sehe ich hoffentlich die Struktur und nehme es in die
Tabelle provider auf. Ist eine ungenaue Methode, aber für die ver-
gleichsweise wenigen Datensätze reicht es mir als Kriterium. Im oben-
genannten Beispiel wird es wohl '.deu.da.example.net' werden.
Wenn du REVERSE() mit INSTR() kombinierst, koenntest du wohl zumindest schon mal feststellen, ob ein remotehost auf eine deiner hostendungen endet.
remote_host NOT REGEXP CONCAT('^.*',(SELECT hostendung FROM provider))
funktioniert, aber nur solange sich ein einziger Datensatz in der Tabelle
provider befindet, hilft mir natürlich wenig :-(
Aber das mit der Subquery zu kombinieren, dazu sehe ich gerade immer noch keine Moeglichkeit - wird wohl eher auf einen JOIN hinauslaufen, wuerde ich sagen.
Den probiere ich dann mal aus.
Viele Grüße,
Stefan
Hi,
remote_host NOT REGEXP CONCAT('^.*',(SELECT hostendung FROM provider))
funktioniert,
Ich haette das CONCAT jetzt ins Subselect gepackt, aber das duerfte Jacke wie Hose sein -
aber nur solange sich ein einziger Datensatz in der Tabelle
provider befindet, hilft mir natürlich wenig :-(
Ja, wie gesagt, da spielt MySQL bei Vergleichen wie LIKE oder (NOT) REGEXP nicht mit da erwartest es skalare Werte.
Was du braeuchtest, waere wohl eine Kombination von IN() und einem der "loseren" Vergleichsoperatoren - aber sowas scheint's nicht zu geben.
MfG ChrisB
Hello Stefan,
wenn man es genau nimmt, müsstest Du eine eigene Tabellenstruktur mit variabler Tiefe daraus machen.
net
de
com
... hat
example
selfhtml
bitworks
... hat
da
dort
hier
nirgends
... hat
deu
fra
ital
brit
... hat
usw.
Wie geht man denn mit varianten Tiefen bhei den Abhängigkmeiten in den übklichen Normalisierungsmodellen überhauot um? Sind die Normalisierungmodelle überhaupt für variante Strukturen geeignet?
Liebe Grüße
Tom vom Berg
Moin!
Wesentlich einfacher - und wohl auch performanter - koenntest du das haben, wenn du das Datum 'p58E68.dip0.t-ipconnect.de' in zwei Datuemer aufsplittest - Teil-vor-Hostname und Hostname - und in zwei einzelnen Spalten unterbringst.
Waere das eine Option, oder spricht da was anderes ernsthaft dagegen?ja und zwar gibt es Provider, bei denen ist der Hostname nur example.org und
bei anderen ist es 1Cust44.tnt5.fft4.deu.da.example.net - die kann ich dann
technisch nicht trennen. Ab und an prüfe ich manuell, ob ich diese Einträge
einem Provider zuordne oder nicht. Könnte dann, beim zweiten Hostnamen,
'.example.net' oder auch '.tnt5.fft4.deu.da.example.net' werden ...
Deine Datenbanktabellen sind noch suboptimaler aufgebaut, als ich dachte.
Sofern dich die Zuordnung Provider <-> Providerdomains <-> Providerclients interessiert, solltest du mindestens mal drei Tabellen haben, die dann nicht über Strings (nämlich Teile von Client-Domainnamen) verknüpft sind, sondern über vernünftige IDs.
Du hast eine Tabelle Provider, dort werden dem Providernamen IDs zugeordnet.
Eine weitere Tabelle enthält die Domains. Jede Domain kriegt eine Domain-ID zugeordnet, und die ID des Providers, zu dem sie gehört.
Zum Schluß eine Tabelle für die kompletten DNS-Namen. Dort werden die Providerbestandteile entweder gespeichert, oder (weil das redundant ist) direkt durch Angabe der Domain-ID zugeordnet.
Fertig ist die Kiste, und du kannst schön Gruppieren, Ordnen und Statistiken machen.
- Sven Rautenberg
Hallo Sven,
Zum Schluß eine Tabelle für die kompletten DNS-Namen. Dort werden die Providerbestandteile entweder gespeichert, oder (weil das redundant ist) direkt durch Angabe der Domain-ID zugeordnet.
vom Prinzip her ist mir die Sache klar, allerdings sehe ich da den Haken,
dass ich dann sämtliche Hostnamen die Domain-ID zuordnen muß, also da
werden alleine mit der Endung .dip0.t-ipconnect.de im Laufe der Zeit
tausende zusammenkommen. Und bei denen müßte ich dann überall die
Domain-ID zuordnen? Kann man automatisieren, aber wäre es nicht schöner,
wenn ich aus meiner provider-Tabelle die Endung hole und so erkenne, ob
dieser Hostname zu einem bestimmten Provider gehört?
Viele Grüße,
Stefan
Hi,
vom Prinzip her ist mir die Sache klar, allerdings sehe ich da den Haken,
dass ich dann sämtliche Hostnamen die Domain-ID zuordnen muß, also da
werden alleine mit der Endung .dip0.t-ipconnect.de im Laufe der Zeit
tausende zusammenkommen.
Na dann betrachte doch mal, wie viel Speicherplatz du da einsparen kannst, wenn du mehrere Zeichen Hostname durch eine kurze (Big-)INT-ID substituierst :-)
Und bei denen müßte ich dann überall die
Domain-ID zuordnen? Kann man automatisieren,
Sollte man, ja.
aber wäre es nicht schöner,
wenn ich aus meiner provider-Tabelle die Endung hole und so erkenne, ob
dieser Hostname zu einem bestimmten Provider gehört?
"Schoener"?
Du muesstest jedes mal eine relativ aufwendige Abfrage starten, wenn du alle Eintrage haben willst, die auf ".dip0.t-ipconnect.de" enden. (Wie Sven schon sagte, etwas performanter wuerde es wohl, wenn du's gleich umgedreht speicherst, so dass die DB dann wenigstens einen Index nutzen kann.)
Stattdessen einmal die ID zu ".dip0.t-ipconnect.de" aus der entsprechenden Tabelle zu lesen, und damit in der anderen Tabelle auf die Suche zu gehen - das erschiene mir doch "schoener".
MfG ChrisB
Moin!
Deine Frage nach
Verwende die Funktion REVERSE():
verbunden mit deinem Anliegen
... WHERE remote_host NOT LIKE '%(SELECT hostendung FROM provider)' ...
Ganz so einfach geht es ja leider nicht :-(
bedeutet nur eines: Du hast eine suboptimale Datenstruktur gewählt, die du vor dem Weitermachen lieber schnell auf brauchbare Werte änderst.
Die für deine Zwecke offensichtlich brauchbarere Form eines Domainnamens ist "de.t-online.dip01.p1278788".
Speichere den Namen also direkt "umgekehrt" in der Tabelle ab. Wenn du ständig die Sortierung mit REVERSE() und das aussortieren mit LIKE %domain machen mußt, kann deine Datenbank das nicht mit Indizierung beschleunigen - ist also auf lange Sicht sehr suboptimal.
Wäre blöd, wenn du das erst bemerkst, wenn nennenswert viele Daten in der DB stehen.
- Sven Rautenberg
Hallo Sven,
Speichere den Namen also direkt "umgekehrt" in der Tabelle ab. Wenn du ständig die Sortierung mit REVERSE() und das aussortieren mit LIKE %domain machen mußt, kann deine Datenbank das nicht mit Indizierung beschleunigen - ist also auf lange Sicht sehr suboptimal.
worauf ich schon in meiner ersten Antwort hinwies. :-)
Und da wußte ich noch nicht, um was es Stefan geht.
Freundliche Grüße
Vinzenz
Hallo,
Ausnahmsweise will ich da mal noch eine kleine (?) Frage dranhängen. Also
ich habe in der Tabelle eigentlich jeden Menge Hostnamen stehen, so z.Bsp.p58E68.dip0.t-ipconnect.de
pD30B8.dip0.t-ipconnect.de
p5B1C8.dip0.t-ipconnect.deUnd in einer anderen Tabelle stehen für die verschiedenen Provider (bzw.
die Backbone-Provider) die typischen Endungen, hier wäre es dann
'.dip0.t-ipconnect.de'. Wie kann ich jetzt nur die Hostnamen ausgeben,
die nicht schon als Provider eingetragen sind?... WHERE remote_host NOT LIKE '%(SELECT hostendung FROM provider)' ...
Ganz so einfach geht es ja leider nicht :-(
Die Hostendungen können unterschiedlich lang sein und ich kann quasi nur
vergleichen, ob in provider (Spalte hostendung) der remote_host vorkommt.
nur als Info, habe mir Eure Kommentare hier im Thread aufmerksam durchge-
lesen und jetzt noch jedem Provider eine eindeutige ID gegeben. Dann läuft
ein Script und versucht bei allen Hostnamen ohne Providerzuordnung jeweils
einen anhand der Endung zuzuordnen. Da ich meist nur eine Endung pro Pro-
vider habe, kann ich mir momentan eine weitere Tabelle, wo dann die ver-
schiedenen Endungen den Providern zugeordnet sind, sparen. Die könnte ich
auch noch später anlegen. Überhaupt ist die ganze Sache auch noch nach-
träglich modifizierbar, die Rohdaten werden ja weiterhin gesammelt und
im schlimmsten Fall muß ich den gesamten Datenbestand nochmal neu aus-
werten, wenn ich die dahinterfolgende Struktur ändere.
Viele Grüße,
Stefan
Hi,
Mein Ziel ist, dass intern die Strings "umgedreht" werden, also 'dcba',
'fdsad' und 'eraa' und danach die Sortierung stattfindet.Gibt es da eine Möglichkeit, dass ich diese Sache in einem SELECT unter-
bringen kann? Verwendet wird MySQL 5.1 als Datenbank.
Hast du mal selber im Manual nachgeschaut, was sich bei den Stringfunktionen nuetzliches finden koennte - oder beschraenkt sich dein Verstaendnis von "Suchen" darauf, andere dies fuer dich tun zu lassen?
Ein Blick auf das Kapitel Stringfunktionen, und ich finde REVERSE() - wieso du nicht?
MfG ChrisB
Hallo ChrisB,
Hast du mal selber im Manual nachgeschaut, was sich bei den Stringfunktionen nuetzliches finden koennte - oder beschraenkt sich dein Verstaendnis von "Suchen" darauf, andere dies fuer dich tun zu lassen?
eher nicht, siehe </archiv/> ;-)
Ein Blick auf das Kapitel Stringfunktionen, und ich finde REVERSE() - wieso du nicht?
Hatte nach 'SQL reverse' gegoogelt, aber leider Tomaten auf den Augen :-/
Viele Grüße,
Stefan
Hallo Stefan,
Schön, mal wieder etwas von Dir zu lesen. :-)
Viele Grüße,
Christian