Window 函数查询问题?

Window function query issue?

编写一个 SQL 查询来报告在首次登录后的次日再次登录的玩家比例,四舍五入到小数点后两位。换句话说,你需要计算从第一次登录开始至少连续两天登录的玩家人数,然后除以玩家总数。

查询结果格式如下例

Example 1:

Input: 
Activity table:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1         | 2         | 2016-03-01 | 5            |
| 1         | 2         | 2016-03-02 | 6            |
| 2         | 3         | 2017-06-25 | 1            |
| 3         | 1         | 2016-03-02 | 0            |
| 3         | 4         | 2018-07-03 | 5            |
+-----------+-----------+------------+--------------+
Output: 
+-----------+
| fraction  |
+-----------+
| 0.33      |
+-----------+
Explanation: 
Only the player with id 1 logged back in after the first day he had logged in so the answer is 1/3 = 0.33

使用此查询时 this leetcode 问题是通过所有测试用例:

WITH temp AS(
    SELECT player_id,
    event_date - LAG(event_date, 1) OVER (PARTITION BY player_id ORDER BY event_date) AS difference, 
    RANK() OVER (PARTITION BY player_id ORDER BY event_date) as rn
    FROM activity
),

tp AS
(
    SELECT count(distinct(player_id)) as all_players
    FROM activity
)

SELECT ROUND(count(t.player_id)/tp.all_players,2) AS fraction

    FROM temp t
    JOIN tp

WHERE t.rn = 2
AND t.difference = 1

当我使用下面的查询时,它不适用于所有测试用例,谁能告诉我为什么上面的查询不起作用:

WITH temp AS(
    SELECT DISTINCT(player_id), difference FROM
    (SELECT player_id, event_date - LAG(event_date, 1) OVER (PARTITION BY player_id ORDER BY event_date) AS difference FROM activity) x WHERE x.difference = 1
),

tp AS
(
    SELECT count(distinct(player_id)) as all_players
    FROM activity
)

SELECT ROUND(COUNT(*)/tp.all_players, 2) as fraction FROM temp, tp;

如果他们的第二次登录是连续的,您将被要求仅计算在内。第一个查询通过仅计算相差 1 的第二行来完成此操作。

WHERE t.rn = 2
AND t.difference = 1

第二个查询将采用任何连续登录。

Demonstration


请注意,两个查询都需要 group by tp.all_players。 MySQL,在某些模式下,有时会为您推断分组方式。但是不要指望它,其他数据库也不会。一边看MySQL Handling of GROUP BY. Consider running MySQL in ANSI mode一边学习SQL,让它更好地遵循标准。