Stefan Einspender: Umgekehrte Sortierung mit ORDER BY

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

  1. 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
    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.

    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

    1. 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
      
      1. 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

        1. 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

          1. 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

            1. 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

              1. 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

                1. 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

                  1. 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

              2. 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

                --
                Nur selber lernen macht schlau
              3. 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

                --
                "Love your nation - respect the others."
                1. 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

                  1. 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

      2. 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

        --
        "Love your nation - respect the others."
        1. 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

      3. 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.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.

        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

  2. 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

    1. 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

  3. Hallo Stefan,

    Schön, mal wieder etwas von Dir zu lesen. :-)

    Viele Grüße,
    Christian