我知道这个问题已经问了好几次了,但是我还没有找到适合我的情况的可行解决方案。

本质上,我的问题出现是因为MySQL不允许视图中的子查询。
我发现了一些解决方法,但它们似乎没有用。

更详细地...

我的第一个表(比赛)存储了用户比赛:

id_tournament | id_competition | id_user | result
-------------------------------------------------
       1      |        1       |     1   |   10
       1      |        1       |     2   |   30
       1      |        2       |     1   |   20
       1      |        2       |     3   |   50
       1      |        3       |     2   |   90
       1      |        3       |     3   |   100
       1      |        3       |     4   |   85


在此示例中,存在三个竞赛:

(
    user1 vs. user2,
    user1 vs. user3,
    user2 vs. user3 vs. user4
)


我的问题是我需要定义一个视图,让我在每场比赛中都能获胜。

预期结果:

 id_tournament | id_competition | id_winner
 ------------------------------------------
        1      |        1       |     2
        1      |        2       |     3
        1      |        3       |     3


这可以通过查询解决:

SELECT
    id_tournament,
    id_competition,
    id_user as id_winner
FROM (

    SELECT * FROM competitions ORDER BY result DESC

) x GROUP BY id_tournament, id_competition


但是,此查询使用子查询(视图中不允许使用),因此我的第一个解决方案是将“帮助器视图”定义为:

CREATE VIEW competitions_helper AS (
    SELECT * FROM competitions ORDER BY result DESC
);

CREATE VIEW competition_winners AS (
    SELECT
        id_tournament,
        id as id_competition,
        id_user as winner
    FROM competitions_helper GROUP BY id_tournament, id_competition
);


但是,这似乎无法给出正确的结果。
结果是:

id_tournament | id_competition | id_winner
------------------------------------------
       1      |        1       |     1
       1      |        2       |     1
       1      |        3       |     1


我不明白的是为什么当我使用子查询时它可以工作,为什么它在视图中使用完全相同的语句给出不同的结果。

感谢您的任何帮助,非常感谢。

最佳答案

这是由于GROUP BY behaviour


  在这种情况下,服务器可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是不确定的,这可能不是您想要的。


我将以这种方式解决问题:

CREATE VIEW competitions_helper AS (
    SELECT      id_tournament,
                id_competition,
                MAX(result) as winning_result
        FROM    competitions
    GROUP BY    id_tournament,
                id_competition
);

CREATE VIEW competition_winners AS (
    SELECT      c.id_tournament,
                c.id_competition,
                c.id_user
        FROM    competitions c
    INNER JOIN  competitions_helper ch
            ON  ch.id_tournament = c.id_tournament
            AND ch.id_competition = c.id_competition
            AND ch.winning_result = c.result
);

10-04 21:18
查看更多