我有一张表,我希望从中获得前N个记录.记录按值排序,某些记录具有相同的值.我想在这里做的是获得前N个记录的列表,包括绑定的记录.这就是表中的内容:
+-------+--------+
| Name | Value |
+-------+--------+
| A | 10 |
| B | 30 |
| C | 40 |
| D | 40 |
| E | 20 |
| F | 50 |
+-------+--------+
Run Code Online (Sandbox Code Playgroud)
现在,如果我想得到前3名,那么
SELECT * FROM table ORDER BY Value DESC LIMIT 3
Run Code Online (Sandbox Code Playgroud)
我明白了:
+-------+--------+
| Name | Value |
+-------+--------+
| F | 50 |
| C | 40 |
| D | 40 |
+-------+--------+
Run Code Online (Sandbox Code Playgroud)
我想得到的是这个
+-------+--------+
| Name | Value |
+-------+--------+
| F | 50 |
| C | 40 |
| D | 40 |
| B | 30 |
+-------+--------+
Run Code Online (Sandbox Code Playgroud)
我计算每个记录的排名,所以我真正想要的是获得前N个记录而不是按值排序的前N个记录.这是我计算排名的方式:
SELECT Value AS Val, (SELECT COUNT(DISTINCT(Value))+1 FROM table WHERE Value > Val) as Rank
Run Code Online (Sandbox Code Playgroud)
在T-SQL中,这样做是可以实现的:
SELECT TOP 3 FROM table ORDER BY Value WITH TIES
Run Code Online (Sandbox Code Playgroud)
有没有人知道如何在MySQL中这样做?我知道它可以用子查询或临时表来完成,但我没有足够的知识来完成这个.我更喜欢不使用临时表的解决方案.
这对你有用吗?
select Name, Value from table where Value in (
select distinct Value from table order by Value desc limit 3
) order by Value desc
Run Code Online (Sandbox Code Playgroud)
也许:
select a.Name, a.Value
from table a
join (select distinct Value from table order by Value desc limit 3) b
on a.Value = b.Value
Run Code Online (Sandbox Code Playgroud)
从 MySQL 8 开始,您可以使用窗口函数WITH TIES通过过滤来模拟语义RANK()。例如:
SELECT Name, Value
FROM (
SELECT Name, Value, RANK() OVER (ORDER BY Value DESC) AS rk
FROM table
) t
WHERE rk <= 3
Run Code Online (Sandbox Code Playgroud)
请注意,当更仔细地阅读您的问题时,这并不完全符合您的要求,但它完全符合 T-SQL 通过该TOP n WITH TIES子句可以执行的操作。