17

次の表があります。

表: スコア 私が持っているもの:

+----+---------+
| | ID | 値 |
+----+---------+
| | 1 | 300 |
| | 2 | 300 |
| | 3 | 300 |
| | 4 | 100 |
| | 5 | 200 |
+----+---------+

必要なもの:

+----+---------+
| | ID | 値 |
+----+---------+
| | 1 | 300 |
| | 2 | 300 |
| | 3 | 300 |
--------------

SQLでトップスコアID 1、2、3を「すべて」取得するにはどうすればよいですか。私は(mysqlで)MAXを使い始めましたが、それは1行しか返しません。

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 値を見つけるためのクエリが 1 回だけ実行されるためです (これが絶対的に保証されることが、変数ベースのソリューションを好む理由です)。 . サブクエリ バージョン (JOIN ではなく WHERE) では、そのクエリは行ごとに 1回実行される可能性があります。

でいくつかのクエリ分析をEXPLAIN EXTENDED行いましたが、INNER JOIN メソッドはおそらくすべての提案の中で最も簡潔で最適です (MySQL 変数を使用するのが面倒な環境にいると仮定すると、それでも最もクリーンだと思います)。

パフォーマンス:

いくつかの興味深い議論が行われたので、私はこれらのことを本当に掘り下げて評価することにしました (やり過ぎだと思いますが、より大きな問題に関する楽しくて役立つ知識です)。テーブル全体のスキャンを検出するためのちょっとした分析トリックがあります。問題のサブクエリに追加WHERE (@foo := @foo + 1)し、@foo を 0 に設定し、クエリを実行し、@foo が何であるかを確認します。これは、すべてを網羅するクエリ メトリックではありませんが、MySQL に各行の評価を依頼する頻度について非常に有益な情報となります。サンプル データの「スコア」は次のとおりです (低いほど良い)。

  • @ctrahey (両方): 5 (一度スキャンして MAX を見つけます)
  • @Joe Stefanelli: 25 (行ごとに 1 回スキャン(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 は、NULL 値または空のセットが含まれていない限り、MIN() または MAX() を含む式で次の形式の式を拡張します。

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 に答える