2015-01-06 167 views
0

的單獨列的值我有一個查詢它看起來像:的MySQL獲得最後一個記錄

SELECT max(sp.id) as max_id, p.name as player, max(update_time) as last_seen, min(login_time) as first_seen, s.name as last_server, 
    sum(sp.play_time) as ontime_total, 
    sum(case when login_time > NOW() - INTERVAL 1 DAY then sp.play_time end) as ontime_day, 
    sum(case when login_time > NOW() - INTERVAL 7 DAY then sp.play_time end) as ontime_week, 
    sum(case when login_time > NOW() - INTERVAL 1 MONTH then sp.play_time end) as ontime_month 
    FROM session_player sp 
    INNER JOIN players p ON p.id=sp.player_id 
    INNER JOIN server s ON s.id=sp.server_id 
    WHERE p.name = ? 

結果: enter image description here

問題: Node22不是上次服務器。我正在努力找到一種方法來獲取此查詢中最後一條記錄的服務器。如果可能的話,你將如何解決這個問題,而不需要運行第二個查詢。

(該查詢已經發生取決於用戶2-3S秒,如果可能的話,我想,以避免任何開銷,如果你看到的性能優化的可能性我將不勝感激任何東西。)

這會工作,但其性能可以猜想(4-5s):

SELECT 
    MAX(sp.id) AS max_id, p.name AS player, MAX(update_time) AS last_seen, MIN(login_time) AS first_seen, 
    SUM(sp.play_time) AS ontime_total, 
    SUM(CASE WHEN login_time > NOW() - INTERVAL 1 DAY THEN sp.play_time END) AS ontime_day, 
    SUM(CASE WHEN login_time > NOW() - INTERVAL 7 DAY THEN sp.play_time END) AS ontime_week, 
    SUM(CASE WHEN login_time > NOW() - INTERVAL 1 MONTH THEN sp.play_time END) AS ontime_month, 
    (SELECT s.name 
     FROM session_player sp 
     JOIN players p ON p.id=sp.player_id 
     JOIN server s ON s.id=sp.server_id 
     WHERE p.name = ? 
     ORDER BY sp.id DESC 
     LIMIT 1 
    ) as last_server 
    FROM session_player sp 
    INNER JOIN players p ON p.id = sp.player_id 
    INNER JOIN server s ON s.id = sp.server_id 
    WHERE p.name = ? 
+0

你是如何定義「最後的記錄」? –

+0

關於性能 - 請確保字段player.id,server.id,session_player.player_id和session_player.server_id都被索引,並且(對於myisam至少)它們是索引中的第一項。 – Giles

+0

@ session_player表上的@MarcusAdams max id – user2693017

回答

0

近3個小時的實驗我得到了它,甚至260時間後s更快:

SELECT MAX(pd.id) AS max_id, pd.name AS player, MAX(pd.update_time) AS last_seen, MIN(pd.login_time) AS first_seen, 
    SUM(pd.play_time) AS ontime_total, 
    SUM(CASE WHEN pd.login_time > NOW() - INTERVAL 1 DAY THEN pd.play_time END) AS ontime_day, 
    SUM(CASE WHEN pd.login_time > NOW() - INTERVAL 7 DAY THEN pd.play_time END) AS ontime_week, 
    SUM(CASE WHEN pd.login_time > NOW() - INTERVAL 1 MONTH THEN pd.play_time END) AS ontime_month, 
    (SELECT s.name 
     FROM session_player sp 
     INNER JOIN server s ON s.id=sp.server_id 
     WHERE max(pd.id)=sp.id 
    ) as last_server 
FROM (
    SELECT sp.id AS id, sp.server_id as server_id, p.name AS name, sp.login_time AS login_time, sp.update_time AS update_time, sp.play_time AS play_time 
    FROM session_player sp 
    INNER JOIN players p ON p.id=sp.player_id 
    WHERE p.name = ? 
) as pd 
-1

試試這個:

SELECT sp.id as max_id, p.name as player, max(update_time) as last_seen, 
min(login_time) as first_seen, s.name as last_server, 
sum(sp.play_time) as ontime_total, 
sum(case when login_time > NOW() - INTERVAL 1 DAY then sp.play_time end) as ontime_day, 
sum(case when login_time > NOW() - INTERVAL 7 DAY then sp.play_time end) as ontime_week, 
sum(case when login_time > NOW() - INTERVAL 1 MONTH then sp.play_time end) as ontime_month 
FROM session_player sp 
INNER JOIN players p ON p.id=sp.player_id 
INNER JOIN server s ON s.id=sp.server_id 
WHERE p.name = ? 
group by sp.player_id 
order by sp.id desc limit 1 
+0

我試過類似的,但它只給出一條記錄,所以沒有什麼可以分組或排序。 – user2693017

相關問題