Silas: mysql, sortierung ABC

SELECT * FROM city ORDER by name ASC

So bekomme ich eine Liste mit alle Stadtnamen sortiert nach ABC nur würde ich gerne so eine Art Titelzeile erstellen

A B C D E F G usw.

wobei die Buchstaben bei denen eine Stadt vorhanden ist in der Datenbank, Dickdargestellt werden sollen.

Über einen Ansatz wie man das bewerkstelligen kann, würde ich mich sehr freuen, da ich nicht weis wie ich das machen kann.

  1. Hallo Silas,

    Über einen Ansatz wie man das bewerkstelligen kann, würde ich mich sehr freuen, da ich nicht weis wie ich das machen kann.

    Ich würde das im Verbund mit einer serverseitigen Programmiersprache lösen.

    Gruppenwechsel könnte dein Stichwort sein.

    Bis demnächst
    Matthias

    --
    Signaturen sind bloed (Steel) und Markdown ist mächtig.
  2. Tach!

    nur würde ich gerne so eine Art Titelzeile erstellen

    A B C D E F G usw.

    wobei die Buchstaben bei denen eine Stadt vorhanden ist in der Datenbank, Dickdargestellt werden sollen.

    Aus dem DBMS holst du dir die entsprechenden Daten:

    SELECT DISTINCT den ersten Buchstaben der Städte oder SELECT COUNT(*) FROM deiner tabelle GROUP BY erster Buchstabe der Städte

    Es gibt meines Wissens keine (einfache) Möglichkeit, eine Abfrage zu erstellen, die Datensätze für nicht vorhandene Daten generiert. Du müsstest also in der abfragenden Umgebung diese Daten (A bis Z) erzeugen und dann in der Ergebnismenge des obigen Selects schauen, ob etwas vorhanden ist, um die Entscheidung für eine Hervorhebung zu treffen.

    dedlfix.

    1. SELECT DISTINCT den ersten Buchstaben der Städte

      jetzt habe ich zwei Abfragen, die jede für sich funktionieren, aber wie bekomme ich diese zu einer zusammen?

      $result = mysql_query("select distinct substr(titel,1,1) AS anfangsbuchstabe from cassis_plugin_glossar order by titel asc ") ;
      
      while($row = mysql_fetch_array($result)) 
      	{
      	echo  $row['anfangsbuchstabe'].'<br/>';
      	}
      

      so erhalte ich alle belegten Anfangsbuchstaben

      und hiermit gebe ich das ABC aus:

      for ($i = 65; $i <= 90; $i++) 
      	{
      	echo chr($i);
      	}	
      
      1. Hallo

        SELECT DISTINCT den ersten Buchstaben der Städte

        jetzt habe ich zwei Abfragen, die jede für sich funktionieren,

        Hier ist ja erstmal eine Abfrage, nämlich die, die unten steht, relevant.

        $result = mysql_query("select distinct substr(titel,1,1) AS anfangsbuchstabe from cassis_plugin_glossar order by titel asc ") ;
        
        while($row = mysql_fetch_array($result)) 
        	{
        	echo  $row['anfangsbuchstabe'].'<br/>';
        	}
        

        so erhalte ich alle belegten Anfangsbuchstaben

        und hiermit gebe ich das ABC aus: …

        Ich würde etwas anders als du an die Aufgabe gehen. Du hast erst einmal eine Liste der tatsächlich benutzten Anfangsbuchstaben. Was dir fehlt, ist der Vergleich mit allen möglichen Anfangsbuchstaben. Ich gehe für das Beispiel davon aus, dass es nur lateinische Buchstaben als Anfangsbuchstaben gibt.

        # Überführung des Abfrageergebnisses in ein Array
        $initialLetter = array();
        # mysql_fetch_assoc statt mysql_fetch_array
        while ($row = mysql_fetch_assoc($result)) {
          $initialLetter[] = strtoupper($row['anfangsbuchstabe']);
        }
        

        Überführe das Ergebnis in ein Array namens initialLetter. Buchstaben werden als Großbuchstaben angegeben.

        # Array mit allen Buchstaben des Alphabets
        $alphabet = range("A", "Z");
        $listAlphabet = array();
        

        Zwei Arrays, eines mit allen Buchstaben des Alphabets, ein zweites, welches das Ergebnis der Operation aufnimmt und zur Generierung der Ausgabe dient.

        # Vergleich des Alphabets mit der Rückgabe aus der DB
        foreach ($alphabet as $letter) {
          if (in_array($letter, $initialLetter) === true) {
            # Anfangsbuchstabe vorhanden
            $listAlphabet[$letter] = true;
          } else {
            # Anfangsbuchstabe nicht vorhanden
            $listAlphabet[$letter] = false;
          }
        }
        

        In einer Schleife werden alle Buchstaben des Alphabets aufgerufen und es wird geprüft, ob in der Datenbank Einträge mit dem Buchstaben existieren. Existieren welche, ergibt die Prüfung mit in_array true, sonst false. Das Ergebnis-Array nimmt den Buchstaben als Schlüssel des Eintrags und das (Nicht-)Vorhandensein von Einträgen als booleschen Wert (true, false) auf.

        # Erzeugung der Ausgabe
        $output = '<ul>';
        foreach ($listAlphabet as $key => $val) {
          $output .= '<li>';
          if ($val === true) {
            $output .= '<a href="?letter='. $key .'">'. $key .'</a>';
          } else {
            $output .= $key;
          }
          $output .= '</li>';
        }
        $output .= '</ul>';
        

        Erzeuge eine Liste aller Buchstaben und verlinke den Eintrag, wenn der Wert des Elements true ist (es Einträge zu diesem Buchstaben in der DB gibt).

        Bei Fragen fragen.

        Tschö, Auge

        --
        Es schimmerte ein Licht am Ende des Tunnels und es stammte von einem Flammenwerfer.
        Terry Pratchett, „Gevatter Tod“
      2. Ich muss gestehen, ich bin schon total durcheinander gekommen, Dank Google. Hunderte von Ansätzen und Code Schnippsel, wobei der eine geht der andere wieder nicht, etc. Aber ich glaube ich sage da nichts neues.

        SO, eigentlich müsste es nun funktionieren. doch es geht nicht:

        $result = mysql_query("select distinct substr(name,1,1) AS anfangsbuchstabe from city order by name asc ") ;
         
        for ($i = 65; $i <= 90; $i++) 
        	{
        	while($row = mysql_fetch_assoc($result)) 
        		{
        		if($row['anfangsbuchstabe']==chr($i))
        			{
        			echo "<b>".chr($i)."</b>, ";  
        			}
        		else
        			{
        			echo chr($i).",";
        			}
        	   } 
        	}	
        		
        

        War vorher falsch, jetzt stimmt es. (kommt davon wenn man es nur rüberkopiert)

        $result = mysql_query("select distinct substr(name,1,1) AS anfangsbuchstabe from city order by name asc"

        Hier bekomme ich nur die Anfangsbuchstaben

        dann zähle ich das ABC auf

        for ($i = 65; $i <= 90; $i++)

        und für jeden Buchstaben einmal

        while($row = mysql_fetch_assoc($result))

        um an die einzelnen Treffer zu kommen

        mit

        if($row['anfangsbuchstabe']==chr($i))

        vergleiche ich.

        Aber hier stimmt etwas nicht. Eigentlich müsste es gehen, aber irgendwie stimmen die beiden Ausgangswerte wahrscheinlich doch nicht: In jedem sollte dann irgendwann der gleiche Buchstabe drin sein

        $row['anfangsbuchstabe']

        chr($i)

        doch ist er anscheinend nicht.

      3. Tach!

        jetzt habe ich zwei Abfragen, die jede für sich funktionieren, aber wie bekomme ich diese zu einer zusammen?

        Die Ergebnisse der ersten sammelst du in ein Array. Dann läufst du durch deine zweite und befragt das Array, ob es einen passenden Inhalt hat.

        for ($i = 65; $i <= 90; $i++) { echo chr($i); }

        PHP kennt eine Funktion namens range(), damit kannst du die Buchstaben direkt erzeugen.

        dedlfix.

      4. Moin!

        und hiermit gebe ich das ABC aus:

        for ($i = 65; $i <= 90; $i++) 
        	{
        	echo chr($i);
        	}	
        

        Ich bin ja für Codeklarheit:

        foreach (range("A", "Z") as $letter) {
            echo $letter;
        }
        

        Hat den Vorteil, dass man klar erkennt, von wo bis wo das geht - und erlaubt die Frage, was mit Umlauten sein soll... die würde man nämlich relativ leicht noch in das zu durchlaufende Array der Buchstaben hinzufügen können - was bei deiner ASCII-Code-Zählerei nicht ganz so simpel sein dürfte.

        Grüße Sven

        1. Hallo und guten Morgen,

          Ich bin ja für Codeklarheit:

          foreach (range("A", "Z") as $letter) {
              echo $letter;
          }
          

          Hat den Vorteil, dass man klar erkennt, von wo bis wo das geht - und erlaubt die Frage, was mit Umlauten sein soll... die würde man nämlich relativ leicht noch in das zu durchlaufende Array der Buchstaben hinzufügen können - was bei deiner ASCII-Code-Zählerei nicht ganz so simpel sein dürfte.

          Sollte man zum "Einfügen von Umlauten" wegen der KLARHEIT nicht besser den Normalizer http://php.net/manual/en/class.normalizer.php bemühen? Schließlich müssen wir doch davon ausgehen, dass es sich bei der Codierung nicht um eine Single-Byte-Codierung, sondern eher wahrscheinlich um UTF-8 (oder datenbankintern um "MySQL-Unicode") handelt.

          Die Funktion range() , die PHP hier bietet, sieht aber eher nach einer ASCII-basierten Funktion aus.

          Wie es aber mit der Ordinalität der weiteren den Grundzeichen A-Z (ASCII) zuzuordenden Zeichen aussieht, vermag ich nicht zu sagen...

          Grüße
          TS

          1. Tach!

            Sollte man zum "Einfügen von Umlauten" wegen der KLARHEIT nicht besser den Normalizer http://php.net/manual/en/class.normalizer.php bemühen?

            Vermutlich ist das sinnvoll, wenn beteiligte Systeme für die Umlaute mehrere Unicode-Zeichen verwenden statt ein kombiniertes. Andererseits ist das eine PECL-Erweiterung. Solche sind nicht unbedingt überall vorhanden.

            Schließlich müssen wir doch davon ausgehen, dass es sich bei der Codierung nicht um eine Single-Byte-Codierung, sondern eher wahrscheinlich um UTF-8 (oder datenbankintern um "MySQL-Unicode") handelt.

            Datenbankintern ist nicht relevant, nur die Kodierung, die an der Schnittstelle gesprochen wird. Die darf sich ja der Client wünschen.

            Die Funktion range() , die PHP hier bietet, sieht aber eher nach einer ASCII-basierten Funktion aus.

            Ja, das stört aber nicht, weil ihre Verwendung nur für A-Z vorgesehen ist. Die Umlaute und andere müssen extra hinzugefummelt werden.

            Wie es aber mit der Ordinalität der weiteren den Grundzeichen A-Z (ASCII) zuzuordenden Zeichen aussieht, vermag ich nicht zu sagen...

            dedlfix.