思ったとおりに機能せず、ドキュメント DISTINCTの意味を説明します :それは明確な行についてです :
(出典: https://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として 代わりは。数値列のインデックスは、文字列列のインデックスよりも高速で、使用するスペースも少なくて済みます。