sql里得分> = s.score

问题描述 投票:1回答:2

我有一个关于sql的问题。我有一个问题,看起来像这样。

 +----+-------+
 | 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.Score就像分数列与自身比较。我完全对这部分感到困惑。它是如何工作的?谢谢!

E.

mysql where
2个回答
1
投票

这称为从属子查询(并且可能非常低效)。依赖子查询 - 基本上意味着它不能转换为连接,因为它“依赖于”特定值 - 为输出中的每个结果行运行特定的“依赖”值。在这种情况下,每个结果行已经具有s.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方言(包括MySQL 8.0+)提供“RANK”和“DENSE_RANK”窗口函数来回答这些类型的查询。窗口函数(如果适用)通常比依赖查询快得多,因为查询规划器可以在更高级别进行优化:这些函数也倾向于驯服其他粗略的SQL。

MySQL 8+ SQL语法应该做的伎俩:

select 
  s.Score, 
  DENSE_RANK() over w AS Rank
from Scores s
window w as (order by Score desc)

对于旧版本的MySQL,还有various work-abouts to emulate ROW_NUMBER / Window Functions


2
投票

理解这一点的一种方法是只为示例数据的每一行运行查询。从第一行开始,我们看到得分是4.00。 select子句中的相关子查询:

(select count(distinct Score) from Scores where Score >= s.Score)

将返回1的计数,因为只有一个记录的独特分数大于或等于4.00。数据中的第二条记录也是如此,其得分也为4.00。对于得分3.85,子查询将找到2的明显计数,因为有两个得分大于或等于3.85,即3.854.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
+-------+------+
© www.soinside.com 2019 - 2024. All rights reserved.