草庐IT

mysql - 在 MySQL 中查找下一行/上一行

coder 2023-10-20 原文

我的 PHP 页面查询一个 Files 表,用户可以单击页面上的列以按标题、日期、大小、状态和上传用户的名称进行排序。然后他们可以单击每个文件以在单独的播放器页面中查看它。

我想做的是在播放器中创建上一个/下一个按钮以转到上一个或下一个文件在"file"页面上按顺序。这意味着结果可以按上面列出的任何参数排序。

对于像日期这样的东西,这很简单:

SELECT * FROM Files WHERE date > curdate ORDER BY date LIMIT 1

但是,其他一些参数给我带来了问题:

  • 如何处理上传用户姓名等字符串?

  • 如何处理排序列中的下一项具有相同值的情况?例如,status 是一个介于 0 和 3 之间的整数,大多数文件的状态为 0。如果我在"file"页面上按状态排序,它会首先列出所有状态为 0 的文件,然后是状态 1,等等。所以如果我的当前文件位于状态为 0 的文件中间,如何找出下一个状态也为 0 的文件?

(附:我知道有很多关于这个主题的话题,但我还没有看到一个解决上述特定情况的话题。)

最佳答案

问:上传用户名等字符串如何处理?

答:与您处理日期和数字的方式相同。字符串也是“可订购的”。

问:如何处理排序列中的下一项具有相同值的情况?

答:这与您处理非唯一日期的重复值的方式相同。除了“主要”排序列外,您还需要另一个唯一的“次要”排序列,或者“主要”和“次要”的组合是唯一的。

理想情况下,您在不可为 null 的列上有一个 PRIMARY KEY 或 UNIQUE KEY,可以用作“次要”排序顺序。

“技巧”是保存列表中的当前位置,方法是将主要值和次要值保存在“最后一次看到”的行中,然后在查询中使用该信息来获取“下一个”页面。

    WHERE t.major >= :last_seen_major
      AND (t.major > :last_seen_major OR t.minor > :last_seen_minor)
    ORDER BY t.major ASC, t.minor ASC
    LIMIT 1

从最后一行(在本例中,只有一行)开始,您需要保存主要列和次要列的值,以便可以在同一查询中使用它们来获取“下一个”行。

为了获得最佳查询性能,您需要一个包含 (major, minor) 前导列的索引。

根据您的查询,假设您有一个 id 列,您将执行如下操作:

SELECT f.*
  FROM Files f 
 WHERE f.date >= :last_seen_date
   AND (f.date > :last_seen_date OR f.id > :last_seen_id)
 ORDER BY f.date ASC, f.id ASC
 LIMIT 1

要按其他列排序,请将 WHERE 和 ORDER BY 子句中的 f.date 替换为其他内容,例如f.name.


性能较差的替代方案

另一种非常流行的方法是在 LIMIT 子句中使用“偏移量”。

乍一看,这似乎是一个优雅的解决方案,但它确实存在一些问题。

你可以这样做:

ORDER BY major ASC, minor ASC LIMIT 41,1 

对于“下一个”行,您将偏移量增加 1

ORDER BY major ASC, minor ASC LIMIT 42,1 

这种方法的一个问题是,如果在已经看到的行范围内插入一行,“下一个”查询将返回同一行。因为第 41 行现在是第 42 行。如果有人删除一行,“下一个”查询将跳过一行。而且我不愿意在我的“获取下一行”功能中忍受这种缺陷。并且这种方法仍然需要跟踪列表中的位置,但需要携带一个额外的偏移量,该偏移量实际上不是行的一部分。

这种方法的另一个问题是数据库必须检索行,然后对它们进行排序,最后应用 LIMIT 子句,这可能是大型集合的性能问题。

关于mysql - 在 MySQL 中查找下一行/上一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26289486/

有关mysql - 在 MySQL 中查找下一行/上一行的更多相关文章

  1. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  2. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  3. ETH 徘徊在 1,700 美元附近;下一步是什么? - 2

    以太坊价格分析表明横盘整理,偏向中性。价格从前一交易日的高点1,791美元回落后正在盘整。但是,有趣的是,多头在1,680美元附近持有重要支撑。多头在1,700美元的心理水平附近聚集动能,并准备在接下来的几个交易日推向1,800美元。以太坊价格显示出盘整迹象,因为它形成了多个连续的顶部形态。这种回撤可能是第二大加密货币下一轮上涨的基石。以太坊连续第二个交易日走低。过去10天,价格在1,590-1,760美元的短期区间内盘整。每日烛台高于1,800美元将维持ETH的进一步上涨。ETH价格走低日线图上,以太坊价格在上升趋势线附近获得一轮支撑。来自879.80美元低点的看涨趋势线为ETH买家提供了支

  4. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  5. ruby-on-rails - 在 Rails 中更高效地查找或创建多条记录 - 2

    我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr

  6. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby​​目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin

  7. ruby - 查找重叠的正则表达式匹配项 - 2

    我想找到给定字符串中的所有匹配项,包括重叠匹配项。我怎样才能实现它?#Example"a-b-c-d".???(/\w-\w/)#=>["a-b","b-c","c-d"]expected#Solutionwithoutoverlappedresults"a-b-c-d".scan(/\w-\w/)#=>["a-b","c-d"],but"b-c"ismissing 最佳答案 在积极的前瞻中使用捕获:"a-b-c-d".scan(/(?=(\w-\w))/).flatten#=>["a-b","b-c","c-d"]参见Rubyde

  8. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi

  9. ruby - 在 Ruby 中查找多个正则表达式匹配的模式和位置 - 2

    这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo

  10. Ruby:数组中的下一个/上一个值,循环数组,数组位置 - 2

    假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe

随机推荐