Mysql sql where score>;=s、 得分
我有一个关于sql的问题。我有个问题看起来像这样Mysql sql where score>;=s、 得分,mysql,where,Mysql,Where,我有一个关于sql的问题。我有个问题看起来像这样 +----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 | | 2 | 3.65 | | 3 | 4.00 | | 4 | 3.85 | | 5 | 4.00 | | 6 | 3.65 | +----+-------+ 这个表格叫做“分数”,在这里对分数进行排名后,它会是这样的 +-------+------+ | Score | Rank
+----+-------+
| Id | Score |
+----+-------+
| 1 | 3.50 |
| 2 | 3.65 |
| 3 | 4.00 |
| 4 | 3.85 |
| 5 | 4.00 |
| 6 | 3.65 |
+----+-------+
这个表格叫做“分数”,在这里对分数进行排名后,它会是这样的
+-------+------+
| Score | Rank |
+-------+------+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 2 |
| 3.65 | 3 |
| 3.65 | 3 |
| 3.50 | 4 |
+-------+------+
这是一个示例答案,但我对WHERE后面的部分感到困惑
select
s.Score,
(select count(distinct Score) from Scores where Score >= s.Score)
Rank
from Scores s
order by s.Score Desc;
此分数>=s。分数与自身比较类似于分数列。我对这部分完全感到困惑。它是如何工作的?谢谢大家!
E.这被称为依赖子查询(可能效率很低)。依赖子查询(基本上意味着它不能转换为联接,因为它“依赖”于特定值)针对特定“依赖”值在输出中的每个结果行运行。在这种情况下,每个结果行已经有一个“特定”值s.Score
依赖子查询中的“Score”指的是原始表,而不是外部查询
使用其他别名可能会更清楚:
select
s.Score,
(select count(distinct other_scores.Score)
from Scores other_scores
where other_scores.Score >= s.Score) Rank -- value of s.Score is known
-- and placed directly into dependent subquery
from Scores s
order by s.Score Desc;
“现代”SQL方言(包括)提供了“等级”和“密集等级”窗口函数来回答这些类型的查询。在适用的情况下,窗口函数通常比依赖查询快得多,因为查询规划器可以在更高的级别上进行优化:这些函数还倾向于驯服其他粗糙的SQL
MySQL 8+SQL语法应该做到这一点:
select
s.Score,
DENSE_RANK() over w AS Rank
from Scores s
window w as (order by Score desc)
对于MySQL的旧版本,也存在一些问题。理解这一点的一种方法是只对示例数据的每一行运行查询。从第一行开始,我们看到分数是
4.00
。select子句中的相关子查询:
(select count(distinct Score) from Scores where Score >= s.Score)
将返回计数1,因为只有一条记录的不同分数大于或等于4.00
。数据中的第二条记录也是如此,它的得分也为4.00
。对于分数3.85
,子查询将发现一个不同的计数2,因为有两个分数大于或等于3.85
,即3.85
和4.00
。您可以在整个表中应用此逻辑,使自己确信查询是如何工作的
+-------+------+
| Score | Rank |
+-------+------+
| 4.00 | 1 | <-- 1 score >= 4.00
| 4.00 | 1 | <-- 1 score >= 4.00
| 3.85 | 2 | <-- 2 scores >= 3.85
| 3.65 | 3 | <-- 3 scores >= 3.65
| 3.65 | 3 | <-- 3 scores >= 3.65
| 3.50 | 4 | <-- 4 scores >= 3.50
+-------+------+
+-------+------+
|得分|排名|
+-------+------+
| 4.00 | 1 | = 4.00
| 4.00 | 1 | = 4.00
| 3.85 | 2 | = 3.85
| 3.65 | 3 | = 3.65
| 3.65 | 3 | = 3.65
| 3.50 | 4 | = 3.50
+-------+------+
@TimBiegeleisen Not it:}什么是有效的方法?我可以在谷歌上搜索任何例子或关键词吗?我甚至不知道该搜索什么。lol@Eleanor请参阅-注意,MySQL 8.0添加了asRANK
函数。这里的答案还显示了早期MySQL版本的替代方法。(这表明我已经多年没有使用MySQL了!)@Eleanor如果使用MySQL 8+,我建议使用新的支持和“密集等级”。我还更新了答案以包含链接,并反映出MySQL最终解决了这个覆盖率差距。@Eleanor我已经将链接中的语法“复制”到问题中,并对表中的语法进行了轻微修改,尽管我还没有验证——我不是MySQL用户。YMMV.)