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

MySQL get single column value of last record

我有一个 查询 看起来像:

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 = ?

结果:

问题: Node22 不是最后一台服务器。我正在努力寻找一种方法来获取此查询中最后一条记录的服务器。如果没有 运行 第二个查询,您将如何解决这个问题。

(此查询已花费 2-3 秒,具体取决于用户,如果可能的话,我想避免任何开销,如果您看到性能优化的可能性,我将不胜感激。)

这可行,但您可以猜出它的性能(4-5 秒):

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 = ?

试试这个:

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

经过将近 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