使用以下MySQL表:
+-----------------------------+
+ id INT UNSIGNED +
+ name VARCHAR(100) +
+-----------------------------+
如何按name ASC
排序,如何选择单个行及其在表格中其他行中的位置。因此,如果表数据如下所示,则按名称排序:
+-----------------------------+
+ id | name +
+-----------------------------+
+ 5 | Alpha +
+ 7 | Beta +
+ 3 | Delta +
+ ..... +
+ 1 | Zed +
+-----------------------------+
如何选择获取该行当前位置的Beta
行?我正在寻找的结果集是这样的:
+-----------------------------+
+ id | position | name +
+-----------------------------+
+ 7 | 2 | Beta +
+-----------------------------+
我可以做一个简单的SELECT * FROM tbl ORDER BY name ASC
然后枚举PHP中的行,但是为一行加载一个可能很大的结果集似乎很浪费。
答案 0 :(得分:108)
使用此:
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'
...获得独特的位置值。这样:
SELECT t.id,
(SELECT COUNT(*)
FROM TABLE x
WHERE x.name <= t.name) AS position,
t.name
FROM TABLE t
WHERE t.name = 'Beta'
...会给出相同的价值。 IE:如果第二个位置有两个值,当第一个查询的位置为2到1时,它们的位置都为2,而另一个的位置为3 ......
答案 1 :(得分:18)
这是我能想到的唯一方法:
SELECT `id`,
(SELECT COUNT(*) FROM `table` WHERE `name` <= 'Beta') AS `position`,
`name`
FROM `table`
WHERE `name` = 'Beta'
答案 2 :(得分:8)
如果查询很简单并且返回结果集的大小可能很大,那么您可以尝试将其拆分为两个查询。
第一个带有缩小过滤条件的查询只是为了检索该行的数据,第二个查询使用带有COUNT
子句的WHERE
来计算位置。
例如在您的情况下
查询1:
SELECT * FROM tbl WHERE name = 'Beta'
查询2:
SELECT COUNT(1) FROM tbl WHERE name >= 'Beta'
我们在具有2M记录的表中使用此方法,这比OMG Ponies的方法更具可扩展性。
答案 3 :(得分:2)
我有一个非常相似的问题,这就是为什么我不会问同样的问题,但我会在这里分享我做了什么,我还必须使用一个小组,并由AVG订购。 有学生,有签名和社交,我不得不对它们进行排名(换句话说,我首先计算AVG,然后在DESC中对它们进行排序,然后最后我需要添加位置(排名为我),所以我做了这里非常相似 最佳答案
我最后在外部SELECT
中放了position
(我的排名)列
SET @rank=0;
SELECT @rank := @rank + 1 AS ranking, t.avg, t.name
FROM(SELECT avg(students_signatures.score) as avg, students.name as name
FROM alumnos_materia
JOIN (SELECT @rownum := 0) r
left JOIN students ON students.id=students_signatures.id_student
GROUP BY students.name order by avg DESC) t
答案 4 :(得分:1)
表中行的位置表示比目标行“更好”的行数。
所以,你必须计算这些行。
SELECT COUNT(*)+ 1 FROM table
WHERE name
&lt;'Beta'
如果出现平局,则返回最高位置。
如果在现有的“Beta”行之后添加另一行名称为“Beta”的行,则返回的位置仍为2,因为它们将在分类中共享相同的位置。
希望这有助于将来会搜索类似内容的人,因为我相信问题所有者已经解决了他的问题。
答案 5 :(得分:1)
其他答案对我来说似乎太复杂了。
这里有一个简单的示例,假设您有一个包含列的表:
userid | points
,您想按点对用户标识进行排序并获得行位置(用户的“排名”),然后使用:
SET @row_number = 0;
SELECT
(@row_number:=@row_number + 1) AS num, userid, points
FROM
ourtable
ORDER BY points DESC
num
为您提供行位置(排名)。
如果您拥有MySQL 8.0+,则可能要使用ROW_NUMBER()
答案 6 :(得分:1)
我正在接受被接受的答案,它似乎有点复杂,所以这里是它的简化版本。
SELECT t,COUNT(*) AS position FROM t
WHERE name <= 'search string' ORDER BY name
答案 7 :(得分:0)
我遇到了类似的问题,需要表格order by votes desc
的等级(索引)。以下对我来说很好用。
Select *, ROW_NUMBER() OVER(ORDER BY votes DESC) as "rank"
From "category_model"
where ("model_type" = ? and "category_id" = ?)
答案 8 :(得分:-7)
可能是您需要的添加语法
LIMIT
所以使用
SELECT * FROM tbl ORDER BY name ASC LIMIT 1
如果你只需要一行..