【发布时间】:2009-05-25 17:12:25
【问题描述】:
如果我这样做
SELECT * FROM mytable ORDER BY mycolumn ASC;
我得到一个按特定顺序排列的结果表。
在给定 PK 的情况下,SQL 中有没有一种方法可以有效地找出结果表中的哪个位置会包含我的 PK 的记录?
【问题讨论】:
标签: sql sql-order-by
如果我这样做
SELECT * FROM mytable ORDER BY mycolumn ASC;
我得到一个按特定顺序排列的结果表。
在给定 PK 的情况下,SQL 中有没有一种方法可以有效地找出结果表中的哪个位置会包含我的 PK 的记录?
【问题讨论】:
标签: sql sql-order-by
您可以计算您正在排序的值的值低于您知道其键值的记录的记录数:
select count(*)
from mytable
where mycolumn < (select mycolumn from mytable where key = 42)
【讨论】:
在支持它的数据库上,您可以为此目的使用 ROW_NUMBER():
SELECT RowNr
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY mycolumn) AS RowNr,
mycolumn
FROM mytable
) sub
WHERE sub.mycolumn = 42
该示例假设您正在寻找主键 42 :)
子查询是必要的,因为类似:
SELECT
ROW_NUMBER() OVER (ORDER BY mycolumn) AS RowNr
FROM mytable
WHERE sub.mycolumn = 42
总是返回 1; ROW_NUMBER() 在 WHERE 之后起作用,可以这么说。
【讨论】:
SQL 不能那样工作。它是基于集合的,这意味着“该结果表中的位置”对数据库没有意义。
您可以在将 ResultSet 映射到对象集合或对其进行迭代时跟踪位置。
【讨论】:
很遗憾,您无法获得“表格中一行的位置”。
使用 ORDER BY 和 ROW_NUMBER 构造的变体(取决于使用的数据库引擎)可以获得的最佳结果是执行查询的结果集中行的位置。
这个位置不会映射回表中的任何位置,除非 ORDER BY 在一组聚集索引列上,但即便如此,该位置也可能在下一秒失效。
我想知道的是你打算用这个“职位”做什么。
【讨论】:
==> 低于 8.0
SET @row_number = 0;
SELECT
(@row_number:=@row_number + 1) AS num,
myColumn.first,
myColumn.second
FROM
myTable
ORDER BY myColumn.first, myColumn.second
来源:http://www.mysqltutorial.org/mysql-row_number/
==> 大于 8.0
请参阅MySQL ROW_NUMBER() function manual,因为我没有测试。但似乎更喜欢这个功能。
【讨论】:
如果不选择整个记录子集,您将无法判断这一点。如果你的 PK 是整数类型,你可以
select count(*) from mytable
where id <= 10 -- Record with ID 10
order by mycolumn asc
【讨论】: