MySQL在视图之前按组排序(无子查询)

时间:2016-05-25 11:03:11

标签: mysql database subquery views

我意识到这个问题已被问过很多次了,但是我还没有找到适合我案例的解决方案。

基本上我的问题出现是因为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

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

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

1 个答案:

答案 0 :(得分:0)

这是由于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
);