2017-12-25 18 views
1

私はSQLについての質問があります。私はこのような質問があります。sql whereスコア> = s.score

+----+-------+ 
| 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 | 
+-------+------+ 

は、サンプルの答えですが、私は後の部分について混乱しています。

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.

答えて

1

これは依存サブクエリとして知られている(そして非常に非効率的であることができます)。 A 従属サブクエリ - 基本的には、特定の値に「依存」するため結合できません。「依存」値の出力にはすべて結果行がで実行されます。この場合、各結果行はすでにに「特定」の値が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; 

MySQL 8.0+含む)「現代」SQLの方言は、クエリのこれらの種類を答えるために、「RANK」と「DENSE_RANK」ウィンドウ関数を提供しています。 Query Plannerはより高いレベルで最適化できるため、適用可能な場合はウィンドウ関数が依存クエリよりもはるかに高速です。これらの関数は、そうでなければぎこちなく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もありますが。

+0

@TimBiegeleisenありません:} – user2864740

+0

効率的な方法は何ですか? googleで検索できる例やキーワードは何ですか?私は何を検索するか分からない。 lol – Eleanor

+0

@Eleanor https://stackoverflow.com/questions/1895110/row-number-in-mysqlを参照してください。* MySQL 8.0 *は 'RANK'機能を追加しています。そこの答えは、以前のバージョンのMySQLの代替方法も示しています。 (これは私が何年もMySQLを使用していなかったことを示しています!) – user2864740

2

これを理解する方法の1つは、サンプルデータの各行に対してクエリを実行することです。最初の行から始めて、スコアは4.00であることがわかります。 select句における相関サブクエリ:その別個のスコアよりも大きいか4.00に等しい1つのレコードのみが存在するため

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

は、1の数を返します。これは、データの2番目のレコードの場合も同様で、スコアは4.00です。スコア3.85の場合、3.85以上の2つのスコア、つまり3.854.00が存在するため、サブクエリは2の別個のカウントを検出します。このロジックをテーブル全体に適用することで、クエリの仕組みを自分で理解することができます。

+-------+------+ 
| 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 
+-------+------+