我已经解决了大部分问题,但是我在寻找要移动到的页码时遇到了麻烦。最初,我只是循环遍历数据面板中的行,但由于分页,这变得非常低效。相反,我决定直接通过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条记录在该字段中都有相同的值),它就无法工作。我进行了一些挖掘,发现上面的代码每次运行查询时会返回不同的行号。
经过进一步挖掘,我发现如果运行以下查询,我将获得想要的结果
select * from table_a order by column_c
但如果我只是这样包装查询
select * from (select * from table_a order by column_c)
每次运行查询时,记录的顺序都发生了巨大变化。这就解释了为什么行号会改变,因为它实际上正在改变。然而,我无法理解为什么仅仅将查询包装起来就会改变顺序。我在其他数据库引擎中做过这样的操作,所以我认为这可能与MySql有关,但是我一直没有找到相关信息来解释原因。我的假设是,在像这样的查询中包含order by时,其排序可能不会被应用,或者行为不如预期。
接下来,我尝试将行号计数直接移动到主/基本查询中,如下所示:
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 = ?
一旦我这样做,order by 似乎被忽略了,它按照记录在表中出现的顺序计数,而不是按照基本查询中的顺序。
我对理解数据集排序未正确应用时的潜在问题以及查找特定记录所在页面的其他解决方案都很感兴趣。
请注意,我在最终外部查询中使用min,因为最终用户可能会选择多行,并且所有这些行都进入最终的where子句。因此,我想找到最低的行号并移动到该页。