MYSQL窗口函数-获取最后一个值

问题描述 投票:0回答:3

我正在尝试在特定时间范围内获取玩家余额的最后一个值。

我有一个transactions表。

玩家余额不是最大值或最小值。

SELECT  project_id, 
        player_id,
        FIRST_VALUE(balance) OVER (PARTITION BY player_id ORDER BY event_arrival_time DESC) AS balance
FROM transactions
WHERE event_arrival_time BETWEEN '2019-12-02 00:00:00' AND '2019-12-03 23:59:59'
        AND project_id='aaa' 
GROUP BY project_id, player_id

[我得到值,但是如果我使用对单个玩家吹的查询来测试它们,则我会得到不同的余额,并且在期中的某个地方会看到给定的结果余额。

此外,如果我多次运行此查询,则会得到不同的余额,就像它选择了不同的事务一样(我们正在谈论10分钟的差异)。

SELECT * 
FROM transacitions
where event_arrival_time BETWEEN '2019-12-02 00:00:00' AND '2019-12-03 23:59:59'
        AND project_id='aaa' and player_id = 'player1'
ORDER BY event_arrival_time desc

我想获得那个时期的球员名单,以及他们的最新余额(不是MAX值-也许是最大日期)。

mysql sql greatest-n-per-group window-functions
3个回答
2
投票

删除GROUP BY子句,如果需要,请使用DISTINCT中的SELECT

SELECT DISTINCT 
  project_id, 
  player_id,
  FIRST_VALUE(balance) OVER (PARTITION BY player_id ORDER BY event_arrival_time DESC) AS balance
FROM transactions
WHERE event_arrival_time BETWEEN '2019-12-02 00:00:00' AND '2019-12-03 23:59:59'
  AND project_id='aaa'

1
投票

您需要过滤,而不是聚合。

您可以使用相关的子查询来做到这一点:

SELECT project_id, player_id, balance
FROM transactions t
WHERE event_arrival_time = (
    SELECT MAX(t1. event_arrival_time)
    FROM transactions t1
    WHERE 
        t1.player_id = t.player_id
        AND t1.event_arrival_time >= '2019-12-02'
        AND t1.event_arrival_time < '2019-12-03'
        AND t1.project_id = 'aaa' 
    )

为了提高性能,您需要在(project_id, player_id, event_arrival_time)上建立索引。您也可以尝试使用covering索引:(project_id, player_id, event_arrival_time, balance);使用这样的索引,数据库将可能仅通过查看索引来执行整个查询,而无需实际访问基础数据。

您也可以使用窗口功能:


SELECT project_id, player_id, balance
FROM (
    SELECT 
        t.*,
        RANK() OVER(PARTITION BY player_id ORDER BY event_arrival_time DESC) rn
    FROM transactions t
    WHERE
        event_arrival_time >= '2019-12-02'
        AND event_arrival_time < '2019-12-03'
        AND project_id='aaa'
) t
WHERE rn = 1



0
投票

我认为这应该可行。没有样品很难分辨。

SELECT
     t.project_id,
     t.player_id,
     GROUP_CONCAT(t.balance) AS Balance -- supposed to have single value
FROM transacitions t
LEFT JOIN transactions t2 ON t.project_id = t2.project_id AND t.player_id = t2.player_id
AND t.event_arrival_time < t2.event_arrival_time
where t2.player_id IS NULL
AND t.event_arrival_time BETWEEN '2019-12-02 00:00:00' AND '2019-12-03 23:59:59'
GROUP BY t.project_id, t.player_id
ORDER BY t.event_arrival_time desc
© www.soinside.com 2019 - 2024. All rights reserved.