MySQL获取最后一条记录的单列值

时间:2015-01-06 14:08:22

标签: mysql join

我有查询,如下所示:

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-3秒,具体取决于用户,如果可能,我希望避免任何开销,如果您看到性能优化的可能性,我将不胜感激。)

这样可行,但你能猜出它的表现(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 = ?

2 个答案:

答案 0 :(得分:0)

经过近3个小时的实验,我得到了它,甚至比以前快了260倍:

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 :(得分:-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