複数のテーブルを結合してユーザーの「実行」に関連するいくつかのデータを抽出する作業をしています。これには、runID、ユーザー名などの基本が含まれますが、実行時間やお気に入りにも結合されます。
以下のクエリでは、LEFT JOIN
およびuser_run_times
テーブルにrun_favourites
を使用しています。
クエリは、ユーザーのすべての実行、お気に入りの場合は最後に実行された日付、および最速の実行時間を表示する必要があります-そのすべてが表示されますが、複数回ログに記録された場合、お気に入りの数は1を超えます1または0)。
SELECT
user_runs.userID,
user_runs.runID,
`createdBy`,
`username`,
DATE_FORMAT(`dateCreated`,'%d-%m-%Y') `dateCreated`,
COUNT(runFavouriteID) AS favourite,
DATE_FORMAT(MAX(`runDate`),'%d-%m-%Y') AS `lastRan`,
MIN(`runTime`) AS `fastestTime`
FROM
`user_runs`
INNER JOIN `runs` ON user_runs.runID = runs.runID
INNER JOIN `users` ON users.userID = runs.createdBy
LEFT OUTER JOIN `user_run_times` ON user_run_times.runID = user_runs.runID
LEFT OUTER JOIN `run_favourites` ON run_favourites.runID = user_runs.runID
WHERE
user_runs.userID = 4
GROUP BY
runID, user_run_times.runID;
このクエリを改善する方法に関するいくつかの提案を探していますか?現在の出力は次のとおりです。
UserID runID createdBy username dateCreated favourite lastRan fastestTime
4 3 3 bob 11-12-2011 3 27-01-2012 36920030
列favourite
は1つだけを表示する必要があります(run_favourites
には行が1つあるため)が、3つ表示されます(user_run_times
に2つ、run_favourites
に1つ)。
うまくいけば、私はこれをあまり混乱させていません。誰かが私がここで最も多くのように「テキスト」形式でテーブル構造を出力する方法を提案できたら、それらも投稿します。
どんなアドバイスでも感謝します、ありがとう! :)
これは、テーブル構造を見ることのない私のベストショットです
SELECT
user_runs.userID,
user_runs.runID,
`createdBy`,
`username`,
DATE_FORMAT(`dateCreated`,'%d-%m-%Y') `dateCreated`,
COUNT(DISTINCT runFavouriteID) AS favourite,
DATE_FORMAT(MAX(`runDate`),'%d-%m-%Y') AS `lastRan`,
MIN(`runTime`) AS `fastestTime`
FROM
(SELECT * FROM `user_runs` WHERE userID=4) user_runs
INNER JOIN `runs` ON user_runs.runID = runs.runID
INNER JOIN `users` ON users.userID = runs.createdBy
LEFT OUTER JOIN `user_run_times` ON user_run_times.runID = user_runs.runID
LEFT OUTER JOIN `run_favourites` ON run_favourites.runID = user_runs.runID
GROUP BY
user_runs.runID,`createdBy`,`username`,`dateCreated`;
これらのインデックスが必要になります
ALTER TABLE user_runs ADD INDEX userID_runID_ndx (userID,runID);
ALTER TABLE runs ADD INDEX runID_createdBy_ndx (runID,createdBy);
ALTER TABLE runs ADD INDEX createdBy_runID_ndx (createdBy,runID);