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

サブクエリを使用せずにMySQLで複数のクエリを実行する

    思ったとおりに機能せず、ドキュメント DISTINCTの意味を説明します :それは明確なについてです :

    (出典: http://dev.mysql.com /doc/refman/5.7/en/select.html

    ユーザーごとに1つの行を取得するには、ユーザーごとに行をグループ化する必要がありますが、残念ながら、この方法では最新のスコアを取得できません。最大、最小、平均スコア、およびその他の計算値を取得できます。 GROUPBY 集計関数

    クエリ

    これは、必要な値を取得するクエリです:

    SELECT u.fsname, u.emailaddress, la.score 
    FROM users u
    INNER JOIN attempts la                # 'la' from 'last attempt'
        ON u.emailaddress = la.emailaddress
    LEFT JOIN attempts mr                 # 'mr' from 'more recent' (than last attempt)
        ON la.emailaddress = mr.emailaddress AND la.datetime < mr.datetime
    WHERE mr.datetime IS NULL
    

    仕組み

    テーブルusersを結合します (別名 u )テーブル試行を使用 (別名 la 、「最後の試行」の略) emailaddressを使用 一致する列として。これは、クエリにすでに含まれている結合です。エイリアスを追加したのは、その時点からの書き込みが少なくなるためです。

    次に、試行に参加します 再びテーブル(別名 mr 最近」から 最後の試行よりも」) laからの各試行に一致します mrからのすべての試行で 同じユーザーの( emailaddressで識別される )および 最近のdatetime LEFT JOIN laの各行が mrの少なくとも1つの行に一致します 。 laからの行 mrに一致するものがありません datetimeの値が最大の行です emailaddressごとに 。それらはNULLでいっぱいの行と一致します ( mrの場合 一部)。

    最後に、 WHERE 句は、 NULLを持つ行のみを保持します datetime mrから選択された行の列 。これらは、 laからの最新のエントリに一致した行です。 emailaddressの値ごとに 。

    パフォーマンスのコメント

    このクエリを高速に実行するために(任意のクエリ! JOINで使用される列にインデックスが必要です 、 WHERE GROUP BY およびORDERBY 条項。

    emailaddressは使用しないでください テーブル内のattempts ユーザーを識別します。 PKが必要です (主キー)テーブル users それをFKとして使用します (外部キー)テーブル試行 (およびユーザーを参照する他のテーブル)。 emailaddressの場合 PKです テーブルのusers UNIQUE INDEXに変更します 新しいINTEGERAUTO INCREMENTを使用します ed列userId PKとして 代わりは。数値列のインデックスは、文字列列のインデックスよりも高速で、使用するスペースも少なくて済みます。




    1. Rows_sent:12 Rows_examined:549024-mySQLクエリを最適化する方法は?

    2. 行がまだ存在しない場合にのみ行を挿入します

    3. OracleのファイルからCLOBへのデータのコピー

    4. 同じwhere条件の同じテーブルを持つ複数のクエリに対して単一のクエリを作成する