总是增量的mysql行数实现(从1到n排序)

总是增量的mysql行数实现(从1到n排序),mysql,select,sql-order-by,row,Mysql,Select,Sql Order By,Row,我以前的搜索结果(包含对我有帮助的内容)并不令人满意,因为按其他列排序会覆盖@RowNumber的本机排序 考虑我的简化成员下表: row_number | id | firstname | lastname -------------------------------------- 1 | 1 | Steve | Jobs 2 | 2 | Bill | Gates 3 | 3 | Rasmus | Lerdo

我以前的搜索结果(包含对我有帮助的内容)并不令人满意,因为按其他列排序会覆盖
@RowNumber
的本机排序

考虑我的简化
成员
下表:

row_number | id | firstname | lastname
--------------------------------------
1          | 1  | Steve     | Jobs
2          | 2  | Bill      | Gates
3          | 3  | Rasmus    | Lerdorf
4          | 4  | Linus     | Torvalds
由以下查询生成:

SELECT id, firstname, lastname, @RowNumber = @RowNumber + 1 AS row_number
FROM member, (SELECT @RowNumber := 0) AS counter_table
但是,当我要基于某些列而不是行编号或id进行排序时,
行编号
的排序将损坏:

SELECT id, firstname, lastname, @RowNumber = @RowNumber + 1 AS row_number
FROM member, (SELECT @RowNumber := 0) AS counter_table
ORDER BY firstname DESC
结果:

row_number | id | firstname | lastname
--------------------------------------
2          | 2  | Bill      | Gates
4          | 4  | Linus     | Torvalds
3          | 3  | Rasmus    | Lerdorf
1          | 1  | Steve     | Jobs
注意:表、查询和任何其他内容都不是经过测试的示例。现实世界中只有问题本身


我认为这些简单的情况很容易理解和解决。(如果他们有任何问题,请忘记这些小错误,并考虑重要的问题本身)

这应该是显而易见的:先排数,后再订购。< /P>

SELECT * FROM (
  SELECT id, firstname, lastname, @RowNumber = @RowNumber + 1 AS row_number
  FROM member, (SELECT @RowNumber := 0) AS counter_table
) AS sq
ORDER BY firstname DESC
哦,等等。。。实际上,您想要的是另一种方式,先下单,然后下单:

SELECT sq.*, @RowNumber = @RowNumber + 1 AS row_number FROM (
  SELECT id, firstname, lastname
  FROM member
  ORDER BY firstname DESC
) AS sq
CROSS JOIN (SELECT @RowNumber := 0) AS counter_table

您对row_number的实现取决于从数据库返回的结果,这些结果已经按照您显示它们的顺序返回

按firstname排序时失败的原因是,结果是按照主键的顺序从数据库返回的,因此id 1获取第1行,然后再通过firstname(通过文件排序)排序

如果在firstname列上添加索引,则结果将按firstname而不是主键的顺序从数据库中获取,因此行号就可以了

如果对查询执行
EXPLAIN
,您会注意到它可能使用主键作为索引,并使用filesort对结果排序,因为它在firstname上没有索引。顺序发生在从表中获取结果之后

在firstname上添加一个索引,您将看到它将使用firstname上的索引从已经按firstname排序的数据库中获取结果,因此firstname将具有第1行

为了安全起见,您可能需要强制索引

然而,这完全是学术性的,用来解释发生了什么以及您可能如何解决这个问题

最有可能的解决方案是将第一个查询作为子查询执行,并在对结果排序后在外部查询中添加行号。
有些应用程序会在用户想要更改排序顺序的任何时候重新发出查询,但是,有些应用程序会缓存结果,在应用程序中排序,并在应用程序中生成行号。

当然,它会“损坏”。没有规则说明记录集中的行数是多少,因为结果是动态创建的,但有一列表示行数。这就是为什么人们通常在应用程序中而不是在db中执行此功能。rownumber不是表中的静态列,因此列上的任何排序都将始终优先。您可以尝试创建一个以rownumber作为列之一的视图,然后对该视图运行查询。这是因为
ORDER
发生在
SELECT
之后。如果在firstname上添加索引,结果将按顺序返回,而不是稍后排序,因此它将起作用。不过还是有味道。谢谢你们两位。所以剩下的唯一简单方法就是php侧行数。请把你的否定答案贴出来,这样我就可以接受了;谢谢你的评论。请你用一段代码给我澄清一下好吗?这看起来容易吗?CodeIgniter的活动记录并不是100%可以实现的!我想我应该选择PHP侧排的号码。无论如何,谢谢你。如果你最初的解决方案可以在CI中实现,那么这个也应该可以。它没有引入任何新语法。不过,我只是猜测一下,我对城市一无所知,非常感谢你的解决方案。我知道我没有提到我是一个CI人。正如我所读到的,不幸的是,子查询实际上是可以实现的,但有一些技巧。不管怎样,我觉得你的解决方案很专业!不过我应该感谢你的帮助+非常感谢你的精彩解释。因此,在我的例子中,用户可能希望按每一列进行排序,PHP端看起来更安全(当然也更容易:D)。