【问题标题】:Next and Previous MySQL row based on name基于名称的下一个和上一个 MySQL 行
【发布时间】:2011-03-04 18:04:41
【问题描述】:

我有一张关于人员详细信息的表格。我想根据个人的姓氏创建一个下一个/上一个链接。由于人员未按字母顺序添加,因此无法根据 ID 选择下一行或上一行。

这是一个很大的表 - 相关字段是 id、name_l 和 name_f。我想按 name_l 订购,个人的姓氏。

我将如何完成这项任务?

谢谢!

编辑 这将在人员详细信息页面上使用,结果将根据当前行生成指向数据库中下一个/上一个条目的链接(按姓氏排序)。例如,如果我正在查看 Joe Hammer,则 Next 链接将链接到 Frank Ingram。

最终代码

感谢 Daniel,这就是我终于开始工作的地方了:

首先,我将增量设置为 0:$i = 0。然后,在使用 while 循环遍历记录时,我将其增加了 1 = $i++。然后,我为该特定条目创建了一个指向详细信息页面的链接:

<a href="details.php?id=<?php echo $member['id'];?>&amp;row=<?php echo $i;?>">Details</a>

在详细信息页面上,我使用以下 SQL 来选择下一条记录:

$row = $_GET['row'];
$getNext = mysql_query("SELECT * FROM members ORDER BY name_l, id LIMIT ".$row.", 1");
$next = mysql_fetch_assoc($getNext);
$nextLink = $row + 1;

最后是链接:

<a href="member_details.php?id=<?php echo $next['id'];?>&amp;row=<?php echo $nextLink;?>"><?php echo $next['name_l'] . ", " . $next['name_f'];?></a>

【问题讨论】:

    标签: php mysql row next


    【解决方案1】:

    尝试更好的 SQL SELECT 语句:

    SELECT * FROM tblPersonnel ORDER BY name_l ASC
    

    试试这个链接了解更多信息: http://w3schools.com/sql/sql_orderby.asp

    【讨论】:

      【解决方案2】:

      首先,确保您的name_l 列已编入索引。然后您可以简单地使用ORDER BYLIMIT 子句,如下所示:

      SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;
      

      只需在LIMIT 子句中增加 0 值即可选择有序集中的下一条记录。因此使用LIMIT 1, 1 获取第二条记录,LIMIT 2, 1 获取第三条记录,以此类推。

      要在name_l 上创建索引,您可以使用CREATE INDEX 命令:

      CREATE INDEX ix_index_name ON personnel (name_l);
      

      测试用例:

      CREATE TABLE personnel (
         id int not null primary key, 
         name_l varchar(10), 
         name_f varchar(10)
      );
      
      CREATE INDEX ix_last_name_index ON personnel (name_l);
      
      INSERT INTO personnel VALUES (1, 'Pacino', 'Al');
      INSERT INTO personnel VALUES (2, 'Nicholson', 'Jack');
      INSERT INTO personnel VALUES (3, 'De Niro', 'Robert');
      INSERT INTO personnel VALUES (4, 'Newman', 'Paul');
      INSERT INTO personnel VALUES (5, 'Duvall', 'Robert');
      

      结果:

      SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;
      +----+---------+--------+
      | id | name_l  | name_f |
      +----+---------+--------+
      |  3 | De Niro | Robert |
      +----+---------+--------+
      1 row in set (0.00 sec)
      
      SELECT * FROM personnel ORDER BY name_l, id LIMIT 1, 1;
      +----+--------+--------+
      | id | name_l | name_f |
      +----+--------+--------+
      |  5 | Duvall | Robert |
      +----+--------+--------+
      1 row in set (0.00 sec)
      
      SELECT * FROM personnel ORDER BY name_l, id LIMIT 2, 1;
      +----+--------+--------+
      | id | name_l | name_f |
      +----+--------+--------+
      |  4 | Newman | Paul   |
      +----+--------+--------+
      1 row in set (0.00 sec)
      

      第一次更新:(进一步到下面的 cmets)

      上面的例子主要适用于如果你从显示第一条记录开始,然后你顺序移动到下一个,也许再下一个,也许一个后退,等等。你也可以很容易地向前移动 x 步和向后移动 x 步,但这似乎不是必需的。

      但是,如果您从随机记录开始,则调整上面的查询以获取下一条和上一条记录将更加困难。

      如果是这种情况,那么您可以简单地保留一个索引计数器来记录您当前所处的位置。您从$index = 0 开始,并使用... LIMIT $index, 1 显示第一条记录。然后通过将$index 增加1 来显示下一个,并通过将$index 减1 来显示上一个。

      另一方面,如果您将呈现人员列表,然后用户将(随机)单击一条记录,您也可以在应用程序端 (php) 的帮助下完成这项工作。假设您向用户呈现以下有序列表:

      +----+-----------+--------+
      | id | name_l    | name_f |
      +----+-----------+--------+  // [Hidden info]
      |  3 | De Niro   | Robert |  // Row 0 
      |  5 | Duvall    | Robert |  // Row 1
      |  4 | Newman    | Paul   |  // Row 2
      |  2 | Nicholson | Jack   |  // Row 3
      |  1 | Pacino    | Al     |  // Row 4
      +----+-----------+--------+
      

      现在,如果用户单击 Newman Paul,您必须将 row=2 参数传递到将显示该员工详细信息的页面。呈现员工详细信息的页面现在知道 Newman Paul 位于第三行 (row=2)。因此,要获取上一条和下一条记录,您只需将LIMIT x, 1 中的x 更改为row - 1 用于上一条记录,row + 1 用于下一条:

      -- Previous 
      SELECT * FROM personnel ORDER BY name_l, id LIMIT 1, 1;
      +----+--------+--------+
      | id | name_l | name_f |
      +----+--------+--------+
      |  5 | Duvall | Robert |
      +----+--------+--------+
      1 row in set (0.00 sec)
      
      
      -- Next 
      SELECT * FROM personnel ORDER BY name_l, id LIMIT 3, 1;
      +----+-----------+--------+
      | id | name_l    | name_f |
      +----+-----------+--------+
      |  2 | Nicholson | Jack   |
      +----+-----------+--------+
      1 row in set (0.00 sec)
      

      第二次更新:

      您可以使用以下 MySQL 特定查询来获取任何随机员工的有序列表中的记录号,然后可以使用该记录号来获取上一条和下一条记录。但请注意,这不是很有效,如果您有数千条记录,可能会降低性能。

      假设您在员工 Nicholson Jack 中。

      您可以执行以下查询:

      SELECT p.id, p.name_l, p.name_f, o.record_number
      FROM   personnel p
      JOIN   (
              SELECT    id,
                        @row := @row + 1 AS record_number
              FROM      personnel
              JOIN      (SELECT @row := -1) r
              ORDER BY  name_l, id
             ) o ON (o.id = p.id)
      WHERE  p.name_l = 'Nicholson' AND p.name_f = 'Jack';
      

      返回这个:

      +----+-----------+--------+---------------+
      | id | name_l    | name_f | record_number |
      +----+-----------+--------+---------------+
      |  2 | Nicholson | Jack   |             3 |
      +----+-----------+--------+---------------+
      1 row in set (0.00 sec)
      

      请注意,如果 id 已知,您可以在 WHERE 子句中使用 p.id = 2,而不是 p.name_l = 'Nicholson' AND p.name_f = 'Jack'

      现在我们可以使用record_number 字段(在这种情况下为3)来获取上一条和下一条记录,只需使用此答案顶部的原始查询,并将LIMIT 2, 1 替换为上一个和LIMIT 4, 1 下一个。给你:

      尼科尔森杰克的前任:

      SELECT * FROM personnel ORDER BY name_l, id LIMIT 2, 1;
      +----+--------+--------+
      | id | name_l | name_f |
      +----+--------+--------+
      |  4 | Newman | Paul   |
      +----+--------+--------+
      1 row in set (0.00 sec)
      

      尼科尔森杰克的下一个:

      SELECT * FROM personnel ORDER BY name_l, id LIMIT 4, 1;
      +----+--------+--------+
      | id | name_l | name_f |
      +----+--------+--------+
      |  1 | Pacino | Al     |
      +----+--------+--------+
      1 row in set (0.00 sec)
      

      【讨论】:

      • 好的,我在 name_l 上创建了一个索引。请查看我的编辑以更好地了解我要完成的工作。谢谢! :)
      • @NightMICU:请查看我的更新答案。这个例子对你有帮助吗?
      • 嘘,在我进一步测试之前,我认为这是解决方案。 :( 使用这个 SELECT 语句,我能够检索下一行(但顺序不正确,接下来解释):“SELECT * FROM person ORDER BY name_l, id LIMIT ".$id.", 1"。看起来这个仅当条目按字母顺序输入时才有效,并且似乎仅适用于检索下一个条目,而不是前一个条目。我可能遗漏了什么吗?或者可能解释得不好?非常感谢您抽出宝贵的时间,Daniel
      • 另一个快速说明 - 这是在仅显示一个查询结果的页面上。例如,假设我们正在查看行 ID 为 3 的 Joe Hammer。下一个人是行 ID 为 10 的 Frank Ingram。
      • @NightMICU: php $id 变量包含什么?在那个地方,它打算有一种从 0 开始的“行号”,这样你就会有 LIMIT 0, 1 获得第一条记录,LIMIT 1, 1 获得第二条记录,LIMIT 2, 1 获得第三条记录,等等。如果您使用这种方法,插入它们的顺序应该无关紧要(如果这在您的应用程序中是可能的)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      相关资源
      最近更新 更多