根据两个文本列排序的 SQL 获取下一行和上一行

Posted

技术标签:

【中文标题】根据两个文本列排序的 SQL 获取下一行和上一行【英文标题】:Get next and previous row based on SQL ordered by two text columns 【发布时间】:2015-02-02 19:17:41 【问题描述】:

我有这个sql语句:

SELECT * FROM members ORDER BY last_name ASC, first_name ASC LIMIT 0, 10

以上用于索引页面。

在详情页,我用

SELECT * FROM members WHERE id = :id

如何根据当前行 id 获取上一行和下一行? (上一个和下一个按last_name ASC,first_name ASC排序)

我想应该是这样的:

SELECT id FROM members WHERE last_name >= : last_name AND id != :id ORDER BY last_name ASC, first_name ASC

但这是不对的。我还需要以某种方式将 first_name 添加到语句中,并且只执行 first_name >= : first_name 不正确。

【问题讨论】:

所以你有一个 id,如果表格是按姓氏排序的,你想要前一个和下一个? @Hogan - 这是正确的 【参考方案1】:

您可以将union allorder bylimit 一起使用。以下内容在第一个子查询中获取前一个名称,在第二个子查询中获取下一个名称:

(select m.*
 from members m
 where last_name < (select last_name from members where id = :id)
 order by last_name desc
 limit 1
) union all
(select m.*
 from members m
 where last_name > (select last_name from members where id = :id)
 order by last_name asc
 limit 1
);

处理名字和姓氏的最简单方法可能是将它们连接在一起:

(select m.*
 from members m
 where concat_ws(' ', last_name, first_name) < (select concat_ws(' ', last_name, first_name) from members where id = :id)
 order by last_name asc, first_name desc
 limit 1
) union all
(select m.*
 from members m
 where concat_ws(' ', last_name, first_name) > (select concat_ws(' ', last_name, first_name) from members where id = :id)
 order by last_name asc, first_name
 limit 1
)

如果名字和/或姓氏中有空格,这可能会产生一些意想不到的结果。我猜数据中不会发生这种情况,但在这种情况下可以使用其他分隔符。

【讨论】:

我认为如果 last_name 上有一个索引,这效果最好——否则你可能想使用@Quassnoi 在这里描述的技术explainextended.com/2009/03/10/… 他在那里使用了一个不需要的组,所以可以简化。

以上是关于根据两个文本列排序的 SQL 获取下一行和上一行的主要内容,如果未能解决你的问题,请参考以下文章

在oracle sql中比较当前行和上一行

PHP MYSQL 下一个和上一行

如何在表中获取下一行和上一行现在行

基于当前行和上一行的用户定义函数

当前行和上一行之间具有特定值的窗口函数

sql 获取分组第一行数据