思ったとおりに機能せず、ドキュメント 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
として 代わりは。数値列のインデックスは、文字列列のインデックスよりも高速で、使用するスペースも少なくて済みます。