lee*_*ers 77 mysql sql analytic-functions
使用以下MySQL表:
+-----------------------------+
+ id INT UNSIGNED +
+ name VARCHAR(100) +
+-----------------------------+
Run Code Online (Sandbox Code Playgroud)
如何排序时,如何选择单个行及其在表中其他行中的位置name ASC.因此,如果表数据如下所示,则按名称排序时:
+-----------------------------+
+ id | name +
+-----------------------------+
+ 5 | Alpha +
+ 7 | Beta +
+ 3 | Delta +
+ ..... +
+ 1 | Zed +
+-----------------------------+
Run Code Online (Sandbox Code Playgroud)
如何选择Beta获取该行当前位置的行?我正在寻找的结果集是这样的:
+-----------------------------+
+ id | position | name +
+-----------------------------+
+ 7 | 2 | Beta +
+-----------------------------+
Run Code Online (Sandbox Code Playgroud)
我可以做一个简单的SELECT * FROM tbl ORDER BY name ASC然后枚举PHP中的行,但是为一行加载一个可能很大的结果集似乎很浪费.
OMG*_*ies 109
用这个:
SELECT x.id,
x.position,
x.name
FROM (SELECT t.id,
t.name,
@rownum := @rownum + 1 AS position
FROM TABLE t
JOIN (SELECT @rownum := 0) r
ORDER BY t.name) x
WHERE x.name = 'Beta'
Run Code Online (Sandbox Code Playgroud)
...获得独特的位置价值.这个:
SELECT t.id,
(SELECT COUNT(*)
FROM TABLE x
WHERE x.name <= t.name) AS position,
t.name
FROM TABLE t
WHERE t.name = 'Beta'
Run Code Online (Sandbox Code Playgroud)
...将给予关系相同的价值.IE:如果第二个位置有两个值,当第一个查询的位置为2到1时,它们的位置都为2,而另一个的位置为3 ......
zer*_*kms 18
这是我能想到的唯一方法:
SELECT `id`,
(SELECT COUNT(*) FROM `table` WHERE `name` <= 'Beta') AS `position`,
`name`
FROM `table`
WHERE `name` = 'Beta'
Run Code Online (Sandbox Code Playgroud)
小智 8
如果查询很简单并且返回结果集的大小可能很大,那么您可以尝试将其拆分为两个查询.
第一个带有缩小过滤条件的查询只是为了检索该行的数据,第二个查询使用COUNTwith WHERE子句来计算位置.
例如在你的情况下
查询1:
SELECT * FROM tbl WHERE name = 'Beta'
查询2:
SELECT COUNT(1) FROM tbl WHERE name >= 'Beta'
我们在具有2M记录的表中使用这种方法,这比OMG Ponies的方法更具可扩展性.
其他答案对我来说似乎太复杂了。
这是一个简单的示例,假设您有一个包含列的表:
userid | points
Run Code Online (Sandbox Code Playgroud)
并且您想按点对用户 ID 进行排序并获取行位置(用户的“排名”),然后使用:
SET @row_number = 0;
SELECT
(@row_number:=@row_number + 1) AS num, userid, points
FROM
ourtable
ORDER BY points DESC
Run Code Online (Sandbox Code Playgroud)
num 给你行位置(排名)。
如果你有 MySQL 8.0+,那么你可能想使用ROW_NUMBER()