17

我有下表:

表:分数 我有什么:

+----+-------+
| 身份证 | 价值 |
+----+-------+
| 1 | 300 |
| 2 | 300 |
| 3 | 300 |
| 4 | 100 |
| 5 | 200 |
+----+-------+

我需要的:

+----+-------+
| 身份证 | 价值 |
+----+-------+
| 1 | 300 |
| 2 | 300 |
| 3 | 300 |
--------------

我将如何在 SQL 中获取“所有”最高分 id 1、2、3。我开始使用 MAX(在 mysql 中),但只返回一行。

4

4 回答 4

46
SELECT Id, value
    FROM Scores
    WHERE value = (SELECT MAX(value) FROM Scores);
于 2012-08-28T21:33:50.160 回答
7

使用快速变量:

SELECT @max := max(value) from scores;
SELECT id, value FROM scores WHERE value = @max;

否则:(我通常坚决反对子查询,但这个是不费吹灰之力的。

SELECT id, value FROM
scores
INNER JOIN (Select max(value) as value from scores) as max USING(value)

请注意,这些都比更基本的 `WHERE value = ( subquery ) 更可取,因为对于它们中的每一个,查找 MAX 值的查询只执行一次(这绝对保证是我更喜欢基于变量的解决方案的原因) . 使用子查询版本(在 WHERE 中,而不是在 JOIN 中),该查询可能每行执行一次。

我用 做了一些查询分析EXPLAIN EXTENDED,INNER JOIN 方法可能是所有建议中最简洁和最优的(假设你在使用 MySQL 变量的环境太麻烦;我仍然认为它是最干净的)。

表现:

由于发生了一些有趣的讨论,我决定真正深入研究并评估这些事情(我知道有点矫枉过正,但在更大的问题上有趣且有用的知识)。检测全表扫描有一些分析技巧;添加WHERE (@foo := @foo + 1)到有问题的子查询中,然后将 @foo 设置为 0,运行查询并查看 @foo 是什么。这不是最终的全部查询收费指标,但它可以提供有关您要求 MySQL 评估每一行的频率的信息。以下是您的样本数据的“分数”(越低越好):

  • @ctrahey(两者):5(扫描一次以找到 MAX)
  • @Joe Stefanelli:25(每行扫描一次(5 * 5))
  • @Jocelyn:17(我无法解释这个,但我很想知道为什么:-)
于 2012-08-28T21:38:49.333 回答
6

在 MySQL 中,您需要使用连接或子查询来执行此操作:

select *
from t
where value = (select max(value) from t)
于 2012-08-28T21:35:05.513 回答
3

使用此查询:

SELECT id, value
FROM Scores
WHERE value>=ALL(SELECT value FROM Scores)

文档:带有 ALL 的子查询

优化子查询

MySQL 使用涉及 MIN() 或 MAX() 的表达式来增强以下形式的表达式,除非涉及 NULL 值或空集:

value {ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery)

例如,这个 WHERE 子句:

WHERE 5 > ALL (SELECT x FROM t)

优化器可能会这样处理:

WHERE 5 > (SELECT MAX(x) FROM t)
于 2012-08-28T21:33:09.803 回答