sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQL-相関するサブクエリが失敗しますか?

    SQLの使用に関するいくつかの重要なポイント:

    • WHERE句では列エイリアスを使用できませんが、HAVING句では使用できます。それがエラーの原因です。
    • 相関サブクエリを使用するよりも、JOINとGROUPBYを使用した方がカウントを向上させることができます。はるかに高速になります。
    • HAVING句を使用してグループをフィルタリングします。

    このクエリの書き方は次のとおりです。

    SELECT t1.id, COUNT(t2.id) AS num_things
    FROM t1 JOIN t2 USING (id)
    GROUP BY t1.id
    HAVING num_things = 5;
    

    このクエリはJOINをスキップできることに気付きました Charles Bretanaのソリューションのように、t1を使用します。ただし、クエリにt1の他の列を含めることをお勧めします。

    Re:コメントの質問:

    違いは、WHERE 句は、GROUP BYの前の行で評価されます グループをグループごとに1行に減らします。 HAVING グループが形成された後、句が評価されます。したがって、たとえば、COUNT()を変更することはできません。 HAVINGを使用したグループの;グループ自体のみを除外できます。

    SELECT t1.id, COUNT(t2.id) as num
    FROM t1 JOIN t2 USING (id)
    WHERE t2.attribute = <value>
    GROUP BY t1.id
    HAVING num > 5;
    

    上記のクエリでは、WHERE 条件に一致する行のフィルター、およびHAVING 少なくとも5つのカウントを持つグループのフィルター。

    ほとんどの人が混乱するのは、GROUP BYがない場合です。 句なので、そうです HAVINGのように およびWHERE 交換可能です。

    WHERE 選択リストの式の前に評価されます。 SQL構文では選択リストが最初に配置されるため、これは明らかではない場合があります。したがって、WHEREを使用すると、コストのかかる計算を大幅に節約できます。 行を制限します。

    SELECT <expensive expressions>
    FROM t1
    HAVING primaryKey = 1234;
    

    上記のようなクエリを使用する場合、選択リストの式はすべての行に対して計算されます。 、HAVINGのため、ほとんどの結果を破棄するだけです 調子。ただし、以下のクエリは、単一行の式のみを計算します。 WHEREと一致する 状態。

    SELECT <expensive expressions>
    FROM t1
    WHERE primaryKey = 1234;
    

    要約すると、クエリは一連の手順に従ってデータベースエンジンによって実行されます。

    1. JOINによって生成された行を含め、テーブルから行のセットを生成します 。
    2. WHEREを評価する 行のセットに対する条件、一致しない行を除外します。
    3. 行セット内のそれぞれの選択リストで式を計算します。
    4. 列エイリアスを適用します(これは別の手順であるため、選択リストの式でエイリアスを使用することはできません)。
    5. GROUP BYに従って、グループをグループごとに1行に凝縮します。 条項。
    6. HAVINGを評価する グループに対する条件、一致しないグループを除外します。
    7. ORDER BYに従って結果を並べ替えます 条項。


    1. SQLServerの宛先とOLEDBの宛先

    2. テーブルから画像データを取得して画像を表示できません

    3. Oracleデータベースから一意の制約列名を取得する

    4. ユーザーのmysqlアクセスが拒否されました(php経由で接続している場合にのみ発生します)