当用作子查询时,查询会产生不同的结果

时间:2019-03-06 12:29:44

标签: mysql

我对这件事有些迷茫-也许我已经为此工作了太多而看不到解决方案?我有一个应用程序,可以处理给定游戏每个季节的玩家注册。我的目标是建立一个图表,显示每个程序每个赛季有多少新球员(一个程序实际上是年龄组)。

此查询是我当前用于执行任务的内容。想法是提取最近5个季节的数据:

select
    `seasons`.*,
    (select COUNT(DISTINCT players.id) from `players`
        where exists (
            select * from `groups`
            inner join `player_season` on `groups`.`id` = `player_season`.`group_id`
            where `players`.`id` = `player_season`.`player_id` and
                `program_id` = 2 and
                `season_id` = seasons.id and
                `paid` is not null and
                `player_season`.`inactive` is null
        ) and not exists (
            select * from `seasons`
            inner join `player_season` on `seasons`.`id` = `player_season`.`season_id`
            where `players`.`id` = `player_season`.`player_id` and
                `seasons`.`id` < seasons.id
        )
    ) as new_players
from `seasons` order by `seasons`.`id` desc limit 5

您可以看到该查询正在对此数据库文件进行操作:https://www.db-fiddle.com/f/k13fnyhecyeGoTKUJvtum9/0将第2季的玩家人数拉为2

当我将它投入生产时,它显示的数字太高了,似乎显然吸引了不应有的玩家。因此,我删除了动态的赛季,并将seasonId硬编码为2,而我得到的只是1个玩家而不是2个,如以下数据库小提琴所示:https://www.db-fiddle.com/f/7k998nxexxY5K85a5ppXJN/0。对于历史背景,这是单季查询:

select
    *
from `players`
where exists (
    select *
    from `groups`
    inner join `player_season` on `groups`.`id` = `player_season`.`group_id`
    where `players`.`id` = `player_season`.`player_id` and
        `program_id` = 2 and
        `season_id` = 2 and
        `paid` is not null and
        `player_season`.`inactive` is null
) and not exists (
    select *
    from `seasons`
    inner join `player_season` on `seasons`.`id` = `player_season`.`season_id`
    where `players`.`id` = `player_season`.`player_id` and
        `seasons`.`id` < 2
)

我已经逐行查询了此查询,没有发现任何可能导致差异的差异。两个db-fiddles中的示例数据完全相同。  为什么此查询用作子查询时会产生不同的结果?

1 个答案:

答案 0 :(得分:1)

该查询使用的是“ 季节”表 两次 ,位于主查询和子查询的第二个条件中。

使用alias来区分两个表引用:

select
    `s1`.*,
    (select COUNT(DISTINCT players.id) from `players`
        where exists (
            select * from `groups`
            inner join `player_season` on `groups`.`id` = `player_season`.`group_id`
            where `players`.`id` = `player_season`.`player_id` and
                `program_id` = 2 and
                `season_id` = s1.id and
                `paid` is not null and
                `player_season`.`inactive` is null
        ) and not exists (
            select * from `seasons` AS s2
            inner join `player_season` on `s2`.`id` = `player_season`.`season_id`
            where `players`.`id` = `player_season`.`player_id` and
                `s2`.`id` < s1.id
        )
    ) as new_players
from `seasons` s1 order by `s1`.`id` desc limit 5