ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySql:查找特定记录的行号

2019-10-30 21:16:20  阅读:166  来源: 互联网

标签:pagination mysql


我正在使用一个通用数据面板,该面板可以具有各种不同的查询来填充该面板.它们可能是从表或视图中选择的简单查询,也可能是用户使用复杂的联接和其他表达式定义自己的复杂查询.我试图修改数据面板,以便如果用户选择一条记录,然后对该表进行排序,那么我会找到该记录现在所在的页面,移至该页面,然后重新选择该记录.

我已经解决了大部分问题,但是我很难找到要移动的页码.我最初只是简单地循环访问数据面板中的行,但是由于页面调度,因此页数越大,效率就越低.相反,我决定直接通过SQL进行此操作,这是我现在遇到的问题.

我决定,如果我可以通过运行产生结果的相同查询来找到所选行的行号,那么我可以计算出我需要移至该页面并跳至该页面的最终页码.我接受了运行以生成结果的查询,并增加了一个变量以获取行号.

原始查询为

select *
from table_a
order by column_c desc

修改后的行号查询变为

select *, (@rownum := @rownum + 1) as rownum
from
(select @rownum := 0) rn
, (
  select *
  from table_a
  order by column_c desc
) data

此时,我正在选择所有记录.然后,我包装上面的查询,并选择记录与我选择的记录匹配的最小行,如下所示

select min(rownum)
from
(  
  select *, (@rownum := @rownum + 1) as rownum
  from
  (select @rownum := 0) rn
  , (
    select *
    from table_a
    order by column_c desc
  ) data
) wrapper
where
  primarykeyfield1 = ?
  and primarykeyfield2 = ?

起初,这似乎是可行的.但是,在测试过程中,我发现,如果我对一个唯一性不够强的字段(例如1000条记录在该字段中具有相同的值)进行排序,则会停止工作.我做了一些挖掘,发现上面的代码每次运行查询时都会返回不同的rownum.

经过一些额外的挖掘,我发现如果要运行以下查询,我会得到想要的结果

select * from table_a order by column_c

但是如果我只是像这样包装该查询

select * from (select * from table_a order by column_c)

每次我运行查询时,记录的顺序都发生了巨大变化.这解释了为什么行num之所以改变是因为实际上它在改变.但是,我无法弄清楚为什么仅通过包装查询即可更改顺序.我已经在其他数据库引擎中完成了此操作,因此我假设它与MySql特别相关,但是我无法找到信息来解释原因.我的推论是,按此类包装在查询中时不应用order by,或者行为不符合预期.

接下来,我尝试将rownum计数直接移到主/基查询中,如下所示

select *, (@rownum := @rownum + 1) as rownum
from (select @rownum := 0) rn, table_a
order by column_c desc

单独运行此查询将创建正确的行号.但是,由于我需要找到所选记录的特定行号,因此必须像这样包装该查询

select min(rownum)
from (
  select *, (@rownum := @rownum + 1) as rownum
  from (select @rownum := 0) rn, table_a
  order by column_c desc
) data
where
  primarykeyfield1 = ?
  and primarykeyfield2 = ?

一旦这样做,顺序by似乎就会被忽略,它将按记录在表中出现的顺序而不是它们在基本查询中的顺序对事物进行计数.

我感兴趣的是,既要了解数据集排序时没有正确应用数据包排序的根本问题,又要了解潜在的其他解决方案,以查找特定记录所在的页码.

注意,我在最终的外部查询上使用min,因为最终用户可以选择多行,并且所有这些行都进入最终的where子句.因此,我想找到最低的行号并移至该页面.

解决方法:

我的目的解决了:)
因此,如果有人认为合适,我会在这里发布:

SELECT d.myRowSerial
FROM (
    SELECT *, @rownum:=@rownum + 1 AS myRowSerial 
    FROM myTable, (SELECT @rownum:=0) AS nothingButSetInitialValue 
    WHERE 1=1 -- Optional: filter if required, otherwise, omit this line;
    ORDER BY AnyColumn -- Apply the order you like; 
) d
WHERE d.myColumn = 'Anything'; -- If you like to limit it to only
-- for any specific row(s), similar to the *MAIN query.

如果您还需要可用于确定分页偏移值的页码,则只需更改上面的第一行,如下所示:

SELECT d.myRowSerial, FLOOR((d.myRowSerial-1)/10) AS pageNumber
-- Say, 10 is per page;

您将在第1页上使用pageNumber == 0,在第2页上使用pageNumber == 1,依此类推…..

标签:pagination,mysql
来源: https://codeday.me/bug/20191030/1970670.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有