web-dev-qa-db-ja.com

WHERE句内でのSELECTステートメントの使用

SELECT * FROM ScoresTable WHERE Score = 
  (SELECT MAX(Score) FROM ScoresTable AS st WHERE st.Date = ScoresTable.Date)

WHERE句内でSELECTステートメントを使用して説明する名前はありますか?これは良い/悪い習慣ですか?

これはより良い選択肢でしょうか?

SELECT ScoresTable.* 
FROM ScoresTable INNER JOIN 
  (SELECT Date, MAX(Score) AS MaxScore 
  FROM ScoresTable GROUP BY Date) SubQuery 
  ON ScoresTable.Date = SubQuery.Date 
  AND ScoresTable.Score = SubQuery.MaxScore

エレガントさははるかに劣りますが、以前のバージョンよりも実行速度が速いようです。 GUIにはっきりと表示されないため(そしてSQL初心者が理解する必要があるため)、私はそれが嫌いです。それを2つの個別のクエリに分割することもできましたが、その後、混乱が生じ始めます...

N.B.日付とスコア(例:名前)だけではありません

9
jofitz

これは相関サブクエリと呼ばれます。用途があります。

6
Mladen Prajdic

それは決して悪い習慣ではありません。これらは通常[〜#〜] subquery [〜#〜][〜#〜] subselectと呼ばれます[〜#〜]またはNESTED QUERY

これは比較的コストのかかる操作ですが、データベースに対して特定の種類の操作を実行する唯一の方法であるため、データベースを処理するときに多くのサブクエリに遭遇することはよくあります。

7

SQL Serverの 分析(またはウィンドウ処理)関数 を使用して、目的の結果を達成するはるかに優れた方法があります。

SELECT DISTINCT Date, MAX(Score) OVER(PARTITION BY Date) FROM ScoresTable

日付と最大スコアの組み合わせ以外にも必要な場合は、次のようなランキング関数を使用できます。

SELECT  *
FROM    ScoresTable t
JOIN (   
    SELECT 
        ScoreId,
        ROW_NUMBER() OVER (PARTITION BY Date ORDER BY Score DESC) AS [Rank] 
        FROM ScoresTable
) window ON window.ScoreId = p.ScoreId AND window.[Rank] = 1

ROW_NUMBER() の代わりに RANK() を使用すると、両方が同じMAX(Score)を共有する複数のレコードを返すことができます。

3
Winston Smith

サブクエリの原則はまったく悪くありませんが、例ではそれを使用するべきではないと思います。私が正しく理解している場合は、各日付の最大スコアを取得したいと考えています。この場合、GROUP BYを使用する必要があります。

2
rael_kid

これは相関サブクエリです。

(これは「ネストされた」クエリです。ただし、これは専門用語ではありません)

内部クエリは外部クエリ(WHERE st.Date = ScoresTable.Date)から値を取得するため、外部クエリの各行に対して1回評価されます。

また、内部クエリ自体が1回だけ実行されるため、内部クエリが独立している非相関フォームもあります。

例えば.

 SELECT * FROM ScoresTable WHERE Score = 
   (SELECT MAX(Score) FROM Scores)

サブクエリの使用に問題はありませんが、必要がない場合を除きます。

ステートメントは、selectステートメントで必要な列に応じて、集計関数として書き換え可能になる場合があります。

SELECT Max(score), Date FROM ScoresTable 
Group By Date
1
BonyT

あなたのケースのシナリオでは、JOININGテーブル自体ではなく、GROUP BYおよびHAVING句を使用しないのはなぜですか。他の便利な機能を使用することもできます。 このリンクを参照

1
dr.Crow

サブクエリは名前です。

時々それが必要ですが、それがどのように適用されるかによって良いか悪いかは異なります。

0
Shamim Hafiz