带有 WHERE 子句的 Rank() 函数不显示任何内容 MYSQL

Rank() function with WHERE clause display nothing MYSQL

所以我必须从他们的每个组织中找到学生的最高分数,我通过应用 RANK() 函数提出了解决方案:

SET SQL_SAFE_UPDATES = 0;

INSERT INTO interviewqs.details(scores,name,organization)
    VALUES
    (30,"Daniel","OWARD UNI"),
    (40,"Kayla","OWARD UNI"),
    (12,"Hope","ZELENSKY UNI"),
    (50,"Osman","ZELENSKY UNI"),
    (4,"Daniel","REWARD UNI"),
    (77,"Joe","REWARD UNI");
DESCRIBE interviewqs.details;

# Find the student with highest scores from each organization
    
SELECT DISTINCT organization,name,scores,
    RANK() OVER (PARTITION BY organization ORDER BY scores DESC)
        AS "rank"
        FROM details
        WHERE "rank" = 1;

问题是当我执行代码时输出显示为空 table,

没有应用 'WHERE' 函数

organization name scores rank 
OWARD UNI   Kayla   40  1
OWARD UNI   Daniel  30  3
REWARD UNI  Daniel  77  1
REWARD UNI  Daniel  30  2
REWARD UNI  Daniel  4   4
ZELENSKY UNI Osman  50  1
ZELENSKY UNI Hope   12  3

应用了 'WHERE' 函数

organization name scores rank 

我这里做错了什么?

您不能在 WHERE 子句中使用 window 函数。原因是 WHERE 子句在 window 函数之前先被处理。我强烈建议您阅读一篇文章,Why Can't I use RANK() in Where Clause

要解决此问题,请将查询更改为使用 CTE 或子查询,如下所示:

子查询:

SELECT organization, name, scores
FROM (
    SELECT 
        organization, name, scores,
        RANK() OVER(PARTITION BY organization ORDER BY scores DESC) AS rnk
    FROM details
) tmp
WHERE rnk = 1
SELECT DISTINCT
       organization,
       FIRST_VALUE(name) OVER (PARTITION BY organization ORDER BY scores DESC) name,
       MAX(scores) OVER (PARTITION BY organization) scores
FROM details

这是使用 CTE 的另一种方式。

WITH tmp AS 
(
  SELECT DISTINCT organization, `name`, scores,
  RANK() OVER (PARTITION BY organization ORDER BY scores DESC) `rank`
  FROM details
)
SELECT organization, `name`, scores FROM tmp WHERE `rank` = 1;

DB Fiddle

注意:rank是保留字,使用时一定要小心,一定要放在反引号中。

查看 MySQL Common Table Expression 了解有关 CTE 的更多详细信息。

In MySQL, every statement or query produces a temporary result or relation. A common table expression or CTE is used to name those temporary results set that exist within the execution scope of that particular statement