【问题标题】:Can select next record alphabetically, but what happens when the record name is identical?可以按字母顺序选择下一条记录,但是当记录名称相同时会发生什么?
【发布时间】:2011-07-12 10:13:37
【问题描述】:

使用这个 sql,我可以使用

的 ID 按字母顺序获取下一个名称
SELECT id 
FROM `names` 
WHERE `name` > (SELECT `name` FROM `names` WHERE `id` = X) 
ORDER BY `name` ASC, `id` ASC

但是让我们假设我有这些我有这些记录

id | name
---------
12 | Alex
8  | Bert
13 | Bert
17 | Bert
4  | Chris

假设我有 id 12 作为参考,我得到了结果

id | name
---------
8  | Bert
13 | Bert
17 | Bert
4  | Chris

但如果我使用 8 作为参考,我会得到

id | name
---------
4  | Chris

Bert 13 和 17 将被跳过。

【问题讨论】:

    标签: mysql select next


    【解决方案1】:

    这可能看起来很明显,但如果您想按 2 个字段(例如名字和姓氏)排序,那么您需要连接 (CONCAT / CONCAT_WS) 名字和姓氏字段以查找前一个或下一个结果。如果您有相同的名称,那么您可能会发现自己从一个名称循环到另一个名称并再次返回,为防止这种情况,请将行的 ID 连接到连接的名字和姓氏的末尾。这将比测试 id 是否大于当前 id (OR n.names = q.name AND n.id > q.id) 更好,因为如果名称没有按字母顺序插入,那么您将错过部分结果(不是浏览到下一个/上一个结果时想要的)。希望这对某人有所帮助。

    【讨论】:

    • 是的,这是正确的解决方案,请看这里(|| 表示连接):SELECT id FROM names WHERE (name || ID) > (SELECT name || ID FROM names WHERE id = X) ORDER BY name ASC ;
    【解决方案2】:

    试试这样的条件:

    WHERE `name` > (SELECT `name` FROM `names` WHERE `id` = X)
          OR `name` = (SELECT `name` FROM `names` WHERE `id` = X) AND `id` > X
    

    【讨论】:

    • 当我通过 12 进行选择时不会跳过记录 8 |亚历克斯
    • 如果您的记录为 12,则为 WHERE name > 'Alex' OR (name = 'Alex' AND id > 12)。对于记录 8,'Bert' > 'Alex',因此不会被跳过。
    【解决方案3】:

    这是因为您将 names 与大于运算符进行比较,这将排除任何等于的名称。如果您想继续尊重 id:

    SELECT n.id 
    FROM names n
    JOIN (SELECT name, id FROM names WHERE id = X) q
      ON n.id = q.id
    WHERE n.name > q.name
       (OR n.names = q.name AND n.id > q.id)
    ORDER BY n.name ASC, n.id ASC
    

    这里我们使用内部查询不仅返回名称,还返回相应的 id。然后,我们可以在名称相同的情况下使用 id 作为 tie-breaker。

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多