Robert: Alpabetisch den nächsten Namen Selektieren

Hallo,

Habe ein kleines Problem mit einer SELECT-Abfrage.

Ich habe eine Art Telefonbuch. In dieser enthalten zb. die Felder: ID, Vorname, Nachname.

Das Problem:
Man soll durch dieses Telefonbuch auch durchblättern können. Wenn ich also bei einem Eintrag bin, sollte ich auf den alphabetisch nächsten bzw. vorhergehenden kommen können.

Soweit bin ich einmal selbst gekommen:
 $next="SELECT mgid,mgvname,mgnname FROM mitglieder WHERE mgnname>'".$mgnname."' ORDER BY mgnname,mgvname LIMIT 0,1";

Das Problem an der Sache ist, dass ich damit den nächst "Höheren" Eintrag selektiere. Personen welchen den selben Nachnamen haben, werden dadurch gänzlich ausgeschlossen. Wie also kann ich den Vornamen ebenfalls beachten.

Also zb:
WAGNER Andreas -> WALLNER Martin -> WALLNER Stefan -> WALLNER Thomas ...

Danke,
Robert

  1. hi,

    Das Problem an der Sache ist, dass ich damit den nächst "Höheren" Eintrag selektiere. Personen welchen den selben Nachnamen haben, werden dadurch gänzlich ausgeschlossen. Wie also kann ich den Vornamen ebenfalls beachten.

    Du suchst also den (ersten) Eintrag, wo entweder der Nachname gleich und der Vorname "größer", oder der Nachname "größer" ist - formuliere das als günstige logische Bedingung, und du solltest am Ziel sein.

    gruß,
    wahsaga

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

    das nennt sich "Duplicate Management" oder "matching duplicates" oder "duplicates chain"

    Man kann das Problem lösen, indem man einen Kombinationsschlüssel aus aktuellem Kernwert und Primary Key (möglichst strict autoincrement) für den Index verwendet.

    Dann kann man die Datensätze in der Reihenfolge des Eintrages der doppelten Werte diese durchblättern, und läuft nicht Gefahr, einen Datensatz auszulassen.

    LG
    Chris

  3. echo $begrüßung;

    Man soll durch dieses Telefonbuch auch durchblättern können. Wenn ich also bei einem Eintrag bin, sollte ich auf den alphabetisch nächsten bzw. vorhergehenden kommen können.
    $next="SELECT mgid,mgvname,mgnname FROM mitglieder WHERE mgnname>'".$mgnname."' ORDER BY mgnname,mgvname LIMIT 0,1";

    Datenbank-Probleme sollten nicht mit Script-Code verfälscht werden.

    Das Problem an der Sache ist, dass ich damit den nächst "Höheren" Eintrag selektiere.

    Wie wäre es, wenn du die Bedingung gänzlich wegließest und beim Blättern anhand von LIMIT-Angaben die entsprechenden Datensätze selektieren würdest?

    echo "$verabschiedung $name";

    1. Hallo,

      Das Problem an der Sache ist, dass ich damit den nächst "Höheren" Eintrag selektiere.

      Wie wäre es, wenn du die Bedingung gänzlich wegließest und beim Blättern anhand von LIMIT-Angaben die entsprechenden Datensätze selektieren würdest?

      Das wäre aber nicht sinnvoll, wenn er Hunderte von Duplicates hätte. Das Problem ist daher überhaupt nicht neu. Den klassischen Lösungsansatz dafür habe ich auch schon gepostet.

      LG
      Chris

      1. echo $begrüßung;

        Das Problem an der Sache ist, dass ich damit den nächst "Höheren" Eintrag selektiere.

        Wie wäre es, wenn du die Bedingung gänzlich wegließest und beim Blättern anhand von LIMIT-Angaben die entsprechenden Datensätze selektieren würdest?

        Das wäre aber nicht sinnvoll, wenn er Hunderte von Duplicates hätte. Das Problem ist daher überhaupt nicht neu. Den klassischen Lösungsansatz dafür habe ich auch schon gepostet.

        Was für Duplikate und woher nimmst du die "Hunderte"?
        Ich interpretiere seine Frage so, dass er in der seiner Tabelle n Datensätze stehen hat, gerade Datensatz Nummer x[*] angezeigt bekommt und nun Datensatz x+1 haben möchte. Dass er sich dabei am Namen orientiert, schreibe ich seiner Unwissenheit zu, wie solch eine Blätterfunktion implementiert werden kann.

        echo "$verabschiedung $name";

        [*] "Nummer" bezieht sich auf die Reihenfolge in der Ergebnisdatenmenge.

        1. hi,

          Ich interpretiere seine Frage so, dass er in der seiner Tabelle n Datensätze stehen hat, gerade Datensatz Nummer x[*] angezeigt bekommt und nun Datensatz x+1 haben möchte. Dass er sich dabei am Namen orientiert, schreibe ich seiner Unwissenheit zu, wie solch eine Blätterfunktion implementiert werden kann.

          Er hat doch eindeutig gesagt, dass er die Namen in alphabetischer Reihenfolge anzeigen möchte.

          Wenn du jetzt behaupten möchtest(? [1]), eine Blätterfunktion mit dieser Anforderung sei über ein Kriterium wie eine Datensatz-ID - die bekanntlich _ausschließlich_ zur Identifikation des Datensatzes, und ganz bestimmt nicht zu Zwecken wie einer Sortierung wie der geforderten dient, zu bewerkstelligen - sollten wir dass dann einer Unwissenheit deinerseits zuschreiben?

          [1] Falls du das nicht so meintest, dann erkläre dich bitte ;-)

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }
          1. echo $begrüßung;

            Er hat doch eindeutig gesagt, dass er die Namen in alphabetischer Reihenfolge anzeigen möchte.

            Wenn du jetzt behaupten möchtest(? [1]), eine Blätterfunktion mit dieser Anforderung sei über ein Kriterium wie eine Datensatz-ID

            Ich sprach nicht von einer ID, sondern von der Reihenfolge in der Ergebnismenge. Und im ursprünglichen Statement steht immer noch eine ORDER BY-Klausel, die dafür sorgen soll[*], dass bei jeder gleichlautenden Abfrage die Datensätze in der gleichen Reihenfolge in die Ergebnismenge eingestellt werden.

            echo "$verabschiedung $name";

            [*] Wenn das Sortierkriterium bei Vor- und Nachnamensgleichheit nicht reicht muss man dieses eben ausreichend erweitern.

            1. Hallo Dedlfix,

              [*] Wenn das Sortierkriterium bei Vor- und Nachnamensgleichheit nicht reicht muss man dieses eben ausreichend erweitern.

              Genau das habe ich doch beschrieben, wie es funktioniert.
              Man nimmt einen Unique-Key hinzu und baut aus dem Duplicate Key und dem Unique Key einen Kombinationsschlüssel.

              Wenn man eine human sinnvolle Reihenfolge erzeugen will, sollte der Unique Key ein strict autoincrement Key sein. Wie man die geforderte Qualität dieses Schlüssels erzeugt, ist allerdings von DBMS zu DBMS unterschiedlich. Bei MySQL reicht diejenige eines autoincrement angelblich nicht von Haus aus, da er (wie hier immer wieder nachzulesen ist) zwischendurch 'Kapriolen' schlagen könnte.

              LG
              Chris

              1. echo $begrüßung;

                [*] Wenn das Sortierkriterium bei Vor- und Nachnamensgleichheit nicht reicht muss man dieses eben ausreichend erweitern.
                Genau das habe ich doch beschrieben, wie es funktioniert.

                Ja, und das hatte ich auch gelesen.

                Man nimmt einen Unique-Key hinzu und baut aus dem Duplicate Key und dem Unique Key einen Kombinationsschlüssel.

                Ich dachte dabei jedenfalls nicht gleich so kompliziert und theoretisch. Das Geburtsdatum hätte ich in die Sortierung einbezogen, vielleicht auch noch den Geburtsort. Wohnort, PLZ, Straße und Hausnummer böten sich ebenso an. Und wenn es dann immer noch nicht eindeutig ist, dann sollte man dem Zufall einen Beschwerdebrief schreiben.

                echo "$verabschiedung $name";

                1. Hallo Dedlfix,

                  Ich dachte dabei jedenfalls nicht gleich so kompliziert und theoretisch.

                  Das ist keinesfalls kompiziert und auch durchaus praxiserprobt.
                  Und außerdem ist es für das Problem zuende gedacht :-))

                  Alle anderen Lösungen stoßen in der Praxis wieder recht schnell an ihre Grenzen.

                  Mein Vorschlag ist allerdings für die Praxis auch noch etwas verbesserungswürdig. Die maximale Länge des Kernschlüssels stellt nämlich ein Ergonomieproblem dar. Entweder, man muss den effektiven Kernschlüssel im Hintergrund merken, oder aber man muss immer viel tippen, oder aber ihn auf z.B. acht Zeichen begrenzen.

                  Aufgrund des beschränkten Speicherplatzes hat man das früher am liebsten gemacht, denn schließlich muss der relevante Teil des Datenfeldes nochmals redundant in den Index aufgenommen werden.

                  Nichts ist also am Ende so goldig, wie es am Anfang glänzt.

                  LG
                  Chris

        2. Hallo,

          [*] "Nummer" bezieht sich auf die Reihenfolge in der Ergebnisdatenmenge.

          eine Ergebnisdatenmenge ist von Haus aus immer unsortiert, es sei denn, man sorgt expliziz für eine Sortierung.

          Um diese in einer Menge gleicher Elemente herzustellen, muss man sie erst einmal indizieren. Das geht nur über einen Hilfsschlüssel. Dieser muss reproduzierbar sein.

          LG
          Chris

          1. yo,

            eine Ergebnisdatenmenge ist von Haus aus immer unsortiert, es sei denn, man sorgt expliziz für eine Sortierung.

            das ist nicht ganz richtig, bzw. ungenau. zum einen sind es die relationen, die unsortiert sind. infolge dessen kann, muss aber nicht die ergebnismenge unsortiert sein. oder mit anderen worten, eine relation ist immer unsortiert, eine ergebnismenge kann. sogar eine nicht expliziet angegebene ergebnismenge kann per "definition" sortiert sein, nämlich genau dann, wenn die ergebnismenge aus einem tupel besteht. und das sind dann keine abfragen, die rein zufällig aus nur einem datensatz bestehen, sondern weil sie nur einen enthalten sollen und müssen, zum beispiel weil sie in unterabfragen eingesetzt werden. aggregat-funktionen funktionen wäre da ein stichwort.

            Um diese in einer Menge gleicher Elemente herzustellen, muss man sie erst einmal indizieren.

            auch das klingt mir ein wenig merkwürdig, warum muss ich etwas indizieren, um gleiche elemente herzustellen ?

            Ilja

  4. yo,

    $next="SELECT mgid,mgvname,mgnname FROM mitglieder WHERE mgnname>'".$mgnname."' ORDER BY mgnname,mgvname LIMIT 0,1";

    Das Problem an der Sache ist, dass ich damit den nächst "Höheren" Eintrag selektiere. Personen welchen den selben Nachnamen haben, werden dadurch gänzlich ausgeschlossen. Wie also kann ich den Vornamen ebenfalls beachten.

    der ansatz ist der falsche. wie dedlfix schon sagt, ist die WHERE klausel überflüssig. der dynamik bekommst du über die LIMIT klausel, mysql hat da wirklich etwas sehr gutes und für den anwender schönes implementiert.

    SELECT mgid,mgvname,mgnname
    FROM mitglieder
    ORDER BY mgnname,mgvname
    LIMIT $variable, 1

    nun musst du zum  beispiel durch den click auf weiter die $variable nur um eins erhöhen und schon sollte der nächste kommen. das einzig kritische ist, falsch in der zwischenzeit noch andere datensätze eingefügt werden. aber das ist dann meistens gar nicht so schlimm, wie es sich im ersten augenblick anhört....

    Ilja

    1. Hallo,

      der ansatz ist der falsche. wie dedlfix schon sagt, ist die WHERE klausel überflüssig. der dynamik bekommst du über die LIMIT klausel, mysql hat da wirklich etwas sehr gutes und für den anwender schönes implementiert.

      Das gilt nur für statische[1] Datenbestände

      [1] statisch zumindest in Bezug auf die Bearbeitung durch den betroffenen User

      LG
      Chris

      1. yo,

        Das gilt nur für statische[1] Datenbestände

        ich bin da recht zuversichtlich, dass es für seine zwecke genau das gesuchte ist. wenn man will, kann man die ORDER BY Klausel noch mit der id erweitern, dann passt das schon.

        ORDER BY mgnname, mgvname, id

        Ilja

        1. Hallo Ilja,

          Das gilt nur für statische[1] Datenbestände

          ich bin da recht zuversichtlich, dass es für seine zwecke genau das gesuchte ist. wenn man will, kann man die ORDER BY Klausel noch mit der id erweitern, dann passt das schon.

          ORDER BY mgnname, mgvname, id

          aber nur "so ungefähr"

          Bei Verwaltungsapplikationen (die nun auch so nach und nach auf 'Webtechnologie' umgestellt werden...) bedarf es doch etwas genauerer Betrachtung.

          LG
          Chris

          1. yo,

            aber nur "so ungefähr"

            bei seiner aufgabe würde ich sagen ziemlich genau.

            Bei Verwaltungsapplikationen (die nun auch so nach und nach auf 'Webtechnologie' umgestellt werden...) bedarf es doch etwas genauerer Betrachtung.

            andere umgebung, andere lösungen. warum sollte ich mir gedanken über etwas machen, was nicht ist ?

            Ilja