Listagem Ordenada Por Letra com PHP E MySQL

Letras exemplificando como fazer listagem por letra com PHP e MySQL.

É bastante comum em determinados tipos de sites e/ou sistemas virtuais ser necessário apresentar listagens de elementos em determinada tabela do banco de dados. Mas muitas pessoas se perguntam como fazer listas por letra a partir do BD. Na verdade, não há muito “mistério” e o segredo está em realizar uma query relativamente simples.

Vamos supor que temos uma tabela no banco de dados. Essa tabela “cidade” guarda informações sobre todas as cidades de um determinado país. Então, em um site fictício, é preciso que se faça uma listagem de todas essas cidades, mas, como são muitas, uma divisão por letra se faz conveninente. Algo como:

  • A
    • Abadia
    • Alagoa
  • B
    • Baiá
    • Boa Esperança
  • C
    • Catanduva
    • Ciabata
    • Cuiabá

E assim por diante.

Técnica do Array

Muitos preferem usar a técnica do array, que, basicamente, consiste em montar um array com todas as letras do alfabeto e, num loop qualquer, realizar as queries para listar todas as cidades que começam com aquela letra.


$letras = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');

É possível trabalhar desse jeito, sim, mas, para casos em que existam letras de outros idiomas, por exemplo, não seria possível codificar sem saber, de antemão, quais seriam estes caracteres. Além disso, montar este array é mais trabalhoso que deixar os próprios PHP+MySQL trabalharem por nós. ;-)

Fazendo da maneira certa

O mais “correto”, para este caso, é realizar uma query para saber quais as letras existentes no BD e, a partir daí, trabalhar com as respectivas listagens. A query é:


$query_letras = mysql_query
('
  SELECT DISTINCT LEFT(descricao_cidade, 1) AS inicial
  FROM cidades
  ORDER BY descricao_cidade
');

Então, montaríamos um array com os resultados:


while($letra = mysql_fetch_object($query_letras))
{
  $letras[] = $letra->inicial;
}

E, a partir disso, poderíamos fazer uma lista composta da seguinte maneira:


foreach($letras AS $letra)
{
  echo '<h3>' . $letra . '</h3>';
          
  $cidades = mysql_query
  ('
    SELECT id, desc
    FROM cidades
      WHERE desc LIKE "' . $letra . '%"
    ORDER BY desc
  ');

  echo '<ul>';
    while ($c = mysql_fetch_object($cidades))
    {
      echo '<li>' . $c->desc . '</li>';
    }
  echo '</ul>';
}

O código completo para a solução:


$query_letras = mysql_query
('
  SELECT DISTINCT LEFT(descricao_cidade, 1) AS inicial
  FROM cidades
  ORDER BY descricao_cidade
');
while($letra = mysql_fetch_object($query_letras))
{
  $letras[] = $letra->inicial;
}

foreach($letras AS $letra)
{
  echo '<h3>' . $letra . '</h3>';
          
  $cidades = mysql_query
  ('
    SELECT desc
    FROM cidades
      WHERE desc LIKE "' . $letra . '%"
    ORDER BY desc
  ');

  echo '<ul>';
    while ($c = mysql_fetch_object($cidades))
    {
      echo '<li>' . $c->desc . '</li>';
    }
  echo '</ul>';
}

Conclusão

Como citado, é muito comum desenvolvedores precisarem fazer listagens por letras e não saberem bem como. Usando a “query-base” apresentada, é possível saber, de antemão, quais serão as letras que comporão a lista e, com isso, ter mais segurança no trabalho que se está fazendo e apresentar um resultado mais fiel ao BD para os visitantes.

Portanto, esta é a maneira correta de se fazer listas por letra usando PHP e MySQL.

Be Sociable, Share!

10 Comentários

  1. Luis

    Olá,estou iniciando na construção de sites e estou aprendendo muita coisa com o site de vocês.
    amigo (a) pretendo inserir em meu site uma situação semelhante a esta, a diferença é que no lugar das letras estarei usando "categorias" e exibir os produtos de cada categoria (no lugar das cidades). Minha duvida é a seguinte: cada categoria possui um numero de ordenação, então posso usar essa mesma função array para numeros?
    desculpe a minha falta de conhecimento, mas como ficaria a montagem do código? exemplo: crio a conexão com o banco via php > seleciono o banco > e coloco declaração SQL acima?

    se puder me ajudar ficaria muito grato.
    obrigado e parabéns pelo site.

    • Tárcio Zemel

      Sim, é possível usar (embora, nesse caso, possa haver uma categoria de número 10 chamada "zoológico" e número 100 chamada "aeroporto", então não ficará em ordem alfabética).

      • vagner25

        Olá tarcio, sou novo no CI, mais ja sei me virar em algumas coisas. Gostaria de tirar 1 duvida. se é possivel fazer 1 drop_down no ci ex: <select><option atrituto = '1'>1</option><option atrituto = '1'>1</option><option atrituto = '2'>2</option></select>
        no entanto quero fazer ele atribuindo o atributo dinamicamente com a informacao vinda do banco de dados. è possivel? TO meio perdido no site aki ainda. qualquer coisa so mandar para: vagner.cerqueira@live.com

  2. kennedy

    Amigo poderia informar qual linguagem de programação???

    qual banco de dados usar dbf, mdb ?? é possivel enviar um arquvo pronto para baixar, grato.

    • Tárcio Zemel

      No caso, a linguagem é PHP e, o Banco, MySQL (veja pela função "mysql_query").

      Mas isso não faz diferença, o mais importante é entender como se faz. Para outros SGBDs, basta aplicar a mesma lógica; o código, em si, vai ser somente um pouco diferente.

      Abraços!

  3. George

    Que Deus abençoe tua vida irmão tava me matando aqui pra fazer isso

  4. Julio

    Boa noite;
    Estou com um GRANDE problema no meu site, no cadastro de BAIRROS no sistema do site esta correto, tudo por ordem alfabética mais no site esta fora da ordem alguns bairros, o código da busca é esse:

  5. Wagner Gilberto

    Olá. Tem uma tabela (tblcadastro) ela contem : ID, nome, endereco, bairro, cidade, uf, cep, email. Criei uma página "agrupadoporbairro.php' com este código:

    ?php header("Content-Type:text/html; charset=ISO-8859-1", true);
    include"../relatorios/config.php";

    $conexao = mysql_connect("$local", "$usuario", "$senha")
     or die(mysql_error());
    $db = mysql_select_db("$selecione")
     or die (mysql_error());

    $query_letras = mysql_query ('SELECT DISTINCT LEFT(bairro, 30) AS inicial FROM tblcadastro ORDER BY bairro');

    while($letra = mysql_fetch_object($query_letras))
    {
      $letras[] = $letra->inicial;
    }

    foreach($letras AS $letra)
    {
      echo '<h3>' . $letra . '</h3>';
              
      $bairro = mysql_query ('SELECT nome  FROM tblcadastro WHERE bairro LIKE "' . $letra . '%" ORDER BY nome');

      echo '';
        while ($c = mysql_fetch_object($bairro))
        {
          echo '' .$c->nome . '';
        }
      echo '';
    }
    ?>

    Funciona, porém, ele esta exibindo todos os nomes antes e depois exibindo os nomes agrupados por bairro

    ex:

    (não quero que mostre isso) mas esta mostrando
     .Rivaldo P de Mcedo
    . Rossano Bezerra do Nascimento
    . Wellington Francisco Torre

    e também mostra isso logo abaixo (que era o esperado

    Engenho do Meio <- este é o bairro
    Jose Jair Soares
    Rosileide Souza dos Santos

    Espinheiro <- este é bairro
    Leonides de Menezes Ferreira
    Maria Odete Lira de Menezes

    Onde estou errando, por que não consigo encontrar.
    Parabéns pelo seu trablaho.

  6. ROBERTO

    SIMPLES E OBJETIVO SEU EXEMPLO DE CÓDIGO, PARABÉNS!

    Segue uma versão da sua ideia para adaptar em WordPress:

    <?php
    $query_letras = $wpdb->get_results("SELECT DISTINCT LEFT(display_name, 1) AS inicial FROM $wpdb->users ORDER BY display_name ASC;");
    foreach($query_letras as $letra)
    {
    $letras[] = $letra->inicial;
    }

    foreach($letras AS $letra)
    {
    echo '<h3>' . $letra . '</h3>';

    $sql = "SELECT * FROM $wpdb->users WHERE display_name LIKE '". $letra . "%' ORDER BY display_name ASC;";
    $resultado = $wpdb->get_results($sql) or die(mysql_error());
    echo '<ul style="text-decoration: none; list-style: none; text-transform: uppercase;">';
    foreach ($resultado as $c){
    $userMetas = get_userdata($c->ID);
    if($userMetas->allcaps['tdp_dealer'] == true || $userMetas->allcaps['subscriber'] == true || $userMetas->allcaps['administrator'] == true){
    ?>

    <a alt="Lista de Aeronaves" href="<?php echo site_url('/');?>perfil-revendedor/?dealer_profile=<?php echo $c->ID; ?>">
    <?php echo $c->display_name; ?>

    <?php
    }
    }
    echo '';
    }
    ?>

    OBRIGADO POR COMPARTILHAR!

Participa! Comenta...