【问题标题】:Is there a better way to create an alphabetic pagination index in PHP/MySQL?有没有更好的方法在 PHP/MySQL 中创建字母分页索引?
【发布时间】:2011-09-29 03:06:19
【问题描述】:

我在 CMS 中进行分页的标准行为之一是在按 alpha 列排序时显示字母快速栏。例如,如果结果按姓氏排序,则在分页下,我会输出一系列链接,从 A 到 Z,以将您直接带到特定第一个字符的页面。

示例:

目前,我正在通过获取该列的所有结果,按字母顺序排序,然后在 PHP 中循环遍历它们并记录记录出现在哪个页面上。当您只处理几百个结果时,这很好用,但我现在正在处理一个可能有几十万行的项目,这根本不是一个可行的选择。

有没有更有效的方法来产生这种索引?请注意,它还需要处理的不仅仅是 A-Z,因为行可能以数字或标点符号开头。

编辑澄清: 我不是在寻找所有第一个字符的简单列表,这很容易。我需要计算以该字符开头的字段将在总结果的哪一页上。所以假设我们正在寻找一个叫 Walter 的人,我有 1000 行,我需要知道 W 的开始位置在 1-1000 范围内的哪个位置。

【问题讨论】:

    标签: php mysql pagination


    【解决方案1】:

    就像在标准分页上只是获取和排序的问题 - 只需添加 WHERE 和 A%(不要忘记在此列上创建索引)

    【讨论】:

      【解决方案2】:
      <?php
      $result1 = mysql_query("SELECT LEFT(name, 1) AS fl FROM comics GROUP BY fl");
      while ($row = mysql_fetch_array($result1))
      {
      $result11 = mysql_query("SELECT * FROM comics WHERE name LIKE '".$row['fl']."%'");
      $countresult11 = mysql_num_rows($result11);
      ?>
      <a href="?sort=<?php echo $row['fl']; ?>" title="<?php echo $countresult11; ?> Comics"><?php echo $row['fl']; ?></a>&nbsp;    
      <?php } ?>
      

      如果你用你的替换我的变量/表名,可能有点像你要找的东西。

      这将检查表格,从每个字母中提取第一个字母,按该字母分组并将其输出为

      1 3 7 9 A B R W X Y Z
      

      取决于您在表格中的内容

      【讨论】:

      • 谢谢,但这不是我想要的。我已将问题更新为更清楚。
      【解决方案3】:

      我认为它是一个 varchar 字段,所以您是否考虑过以下问题:

      SELECT DISTINCT SUBSTRING(lastname FROM 1 FOR 1) FROM mytable;
      

      这将为您提供姓氏首字母的独特列表。

      您还可以使用 UPPER() 来确保您只获得大写字符。 LEFT() 也将实现类似的效果,因此您应该尝试看看哪个在您的数据集上执行得最快。

      编辑:如果您还想要计数:

      SELECT DISTINCT SUBSTRING(lastname FROM 1 FOR 1) AS firstletter, COUNT(*) AS counter FROM mytable GROUP BY firstletter;
      

      无需对每个字母进行第二次查询。

      【讨论】:

      • 问题更新更清晰。我需要的不仅仅是所有第一个字符的列表。
      • 后期编辑:嗯,算了,这可能行得通。使用每个字符的计数来查找它所在的页面。
      • 这非常有效。遍历结果并总结之前所有条目的总数,这正是我正在寻找的结果。谢谢!
      【解决方案4】:
      $sql = "SELECT left(name, 1) AS firstchar FROM mytable ORDER BY name";
      
      $result = mysql_query($sql) or die(mysql_error());
      
      $letters = array();
      $row = 0;
      while($row = mysql_fetch_assoc($result)) {
          $row++;
          if (!isset($letters[$row['firstchar']])) {
              $letters[$row['firstchar']] = $row;
          }
      }
      

      这将为您提供一个以第一个字母为键的数组,以及它们首次出现在该值的行号:

      a => 1,
      b => 50,
      c => 51,
      

      等等……

      可能有某种纯粹在 SQL 中执行此操作的方法,但 MySQL 本身并没有内置任何“行号”支持,因此这将是一个非常难看的查询。

      【讨论】:

      • 这是我之前的做法,但是当查询返回几十万个结果时,这就会崩溃。对于每个页面请求,这简直是太多的处理。
      猜你喜欢
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      • 2012-05-08
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      相关资源
      最近更新 更多