具有多个条件的SQL连接OR / AND不起作用

时间:2014-12-10 09:13:05

标签: mysql sql

我正在尝试基于具有多个条件OR / AND的LEFT连接构建视图。这是多个堆叠视图的第一个视图之一,用于计算3v3格式的Magic the Gathering匹配的排名。

我已经成功构建了2V2格式的相同视图,我正在尝试为3v3重现它,但它不起作用。

小背景:我们是6个朋友的兄弟情谊。我们经常一起玩,但是当我们所有人都在那里时很少见。我们根据在场球员的数量调整游戏格式。如果我们是一个不成对的号码,我们将玩Solo(1 VS ALL),如果我们配对,我们通常在团队中玩(2V2或3V3),但我们也可以独自对抗3或5个其他玩家。每种格式有16种不同的游戏格式(1V1,Solo 3P,Solo 4P,2V2等)所有排名都是由MySQL从堆叠的SQL视图中计算出来的。当我们在团队中进行游戏时,我们会随机组建2支队伍因此,在团队格式中,可以有多个团队组合,但只有一个受限制的数字,因为除了6个玩家基础之外,其他人都不可能。

为了建立2V2和3V3排名,我构建了2个视图,用于计算玩家表中所有可能的团队组合,它看起来像这样:

2v2团队组合:

  P1          P2
Bastien     Charles
Bastien     Francois
Charles     Francois
Bastien     Mathieu
Charles     Mathieu
Francois    Mathieu
Bastien     Thomas
Charles     Thomas
Francois    Thomas
Mathieu     Thomas
Bastien     Valery
Charles     Valery
Francois    Valery
Mathieu     Valery
Thomas      Valery

3v3团队组合:

  P1        P2        P3
Bastien     Charles     Francois
Bastien     Charles     Mathieu
Bastien     Francois    Mathieu
Charles     Francois    Mathieu
Bastien     Charles     Thomas
Bastien     Francois    Thomas
Charles     Francois    Thomas
Bastien     Mathieu     Thomas
Charles     Mathieu     Thomas
Francois    Mathieu     Thomas
Bastien     Charles     Valery
Bastien     Francois    Valery
Charles     Francois    Valery
Bastien     Mathieu     Valery
Charles     Mathieu     Valery
Francois    Mathieu     Valery
Bastien     Thomas      Valery
Charles     Thomas      Valery
Francois    Thomas      Valery
Mathieu     Thomas      Valery

首先,这是收集所有胜利(胜利),每个团队和2V2格式的视图,它按预期工作(请注意" Joueur "表示" 播放器"法语)

select C.P1 AS Joueur1,C.P2 AS JOueur2,count(0) AS Twin,sum(P.Win) AS Pwin 
from MTG_Matchs M 
    join MTG_Matchs_Formats F on M.Format = F.Format
    join VIEW_Matchs_Formats_Points P on P.Format = F.Format
    left join MTG_Matchs_Joueurs J1 on (J1.MatchID = M.ID and J1.Num = 1)
    left join MTG_Matchs_Joueurs J2 on (J2.MatchID = M.ID and J2.Num = 2)
    left join VIEW_Equipes_Combinaisons_2 C on
             ((C.P1 = J1.Joueur) and (C.P2 = J2.Joueur)) 
        or ((C.P2 = J1.Joueur) and (C.P1 = J2.Joueur)) 
where ((F.IsTeam = 1) 
  and (F.NbrJoueurs = 4)
  and (J1.Team = J2.Team)
  and (J2.Win = 1) 
  and (J1.Win = 1)) 
group by C.P1,C.P2

返回结果(比赛表中出现的所有球队组合,总获胜数和获得的总分数):

Joueur1     JOueur2     Twin    Pwin
Charles     Francois    5           150
Francois    Thomas      11          330
Francois    Mathieu     7           210
Mathieu     Thomas      7           210
Bastien     Charles     2           60
Bastien     Thomas      5           150
Charles     Thomas      7           210
Charles     Mathieu     8           240
Francois    Valery      2           60

此查询的关键是在2v2组合表上进行的连接: 左连接VIEW_Equipes_Combinaisons_2 C

由于这很好,我想为3v3重现相同的逻辑 DB中实际上只有5个3v3匹配,有4个不同的团队组合。

以下是Match_Joueurs表中3v3匹配的所有记录:

select  J.*
from MTG_Matchs M 
    join MTG_Matchs_Formats F on (M.Format = F.Format)
    left join MTG_Matchs_Joueurs J on J.MatchID = M.ID
where (F.IsTeam = 1) 
    and (F.NbrJoueurs = 6)   

ID   MatchID  Num  Team   Joueur     Deck   Score   Win 
20     5       1     2    Bastien     207    0       0
18     5       2     1    Charles     144    5       1
22     5       3     2    Francois    203    0       0
19     5       3     1    Mathieu     222    0       1
17     5       1     1    Thomas      208    8       1
21     5       2     2    Valery      194    0       0
28     6       3     2    Bastien     207    10      1
23     6       1     1    Charles     144    0       0
27     6       2     2    Francois    203    10      1
25     6       3     1    Mathieu     222    0       0
24     6       2     1    Thomas      209    0       0
26     6       1     2    Valery      194    20      1
34     7       3     2    Bastien     154    0       0
29     7       1     1    Charles     144    20      1
33     7       2     2    Francois    200    0       0
31     7       3     1    Mathieu     222    0       1
30     7       2     1    Thomas      209    8       1
32     7       1     2    Valery      194    0       0
496    146     3     1    Bastien     222    0       1
499    146     3     2    Charles     154    0       0
495    146     2     1    Francois    209    8       1
494    146     1     1    Mathieu     144    20      1
498    146     2     2    Thomas      200    0       0
497    146     1     2    Valery      194    0       0
502    147     3     1    Bastien     222    0       0
505    147     3     2    Charles     154    0       1
501    147     2     1    Francois    209    0       0
500    147     1     1    Mathieu     144    0       0
504    147     2     2    Thomas      200    0       1
503    147     1     2    Valery      194    0       1

以下查询列出了赢得3v3格式匹配的所有团队(3名玩家),我发布它以便您可以理解应该由3v3视图返回的数据:

select J1.Joueur, J2.Joueur, J3.Joueur 
from MTG_Matchs M 
    join MTG_Matchs_Formats F on (M.Format = F.Format)
    join VIEW_Matchs_Formats_Points P on  P.Format = F.Format
    left join MTG_Matchs_Joueurs J1 on ((J1.MatchID = M.ID) and (J1.Num = 1))
    left join MTG_Matchs_Joueurs J2 on ((J2.MatchID = M.ID) and (J2.Num = 2))
    left join MTG_Matchs_Joueurs J3 on ((J3.MatchID = M.ID) and (J3.Num = 3))
where (F.IsTeam = 1) 
    and (F.NbrJoueurs = 6) 
    and (J1.Team = J2.Team) 
    and (J2.Team = J3.Team) 
    and (J1.Win = 1) 
    and (J2.Win = 1)
    and (J3.Win = 1)

给出了:

   Joueur    Joueur    Joueur
#1 Charles   Thomas    Mathieu
#2 Valery    Francois    Bastien
#3 Valery    Thomas    Charles
#4 Thomas    Charles     Mathieu
#5 Mathieu   Francois    Bastien

请注意,有5个返回的行,但它们仅代表4种组合,因为第1行和第4行是相同的组合,但是玩家的顺序不同。这正是为什么团队组合视图上的正确JOIN是产生一致结果的关键所在。

最后,在这里,应该收集所有胜利(胜利),每队和3V3格式的观点,并计算胜利的数量和总和所获得的点数。我重现了与2v2视图完全相同的逻辑:

select C.P1 AS Joueur1, C.P2 AS Joueur2, C.P3 AS Joueur3, count(0) AS Twin, sum(P.Win) AS Pwin 
from MTG_Matchs M 
    join MTG_Matchs_Formats F on (M.Format = F.Format)
    join VIEW_Matchs_Formats_Points P on  P.Format = F.Format
    left join MTG_Matchs_Joueurs J1 on ((J1.MatchID = M.ID) and (J1.Num = 1))
    left join MTG_Matchs_Joueurs J2 on ((J2.MatchID = M.ID) and (J2.Num = 2))
    left join MTG_Matchs_Joueurs J3 on ((J3.MatchID = M.ID) and (J3.Num = 3))
    left join VIEW_Equipes_Combinaisons_3 C 
        on (
            ((C.P1 = J1.Joueur) and (C.P2 = J2.Joueur) and (C.P3 = J3.Joueur)) 
        or  ((C.P2 = J1.Joueur) and (C.P3 = J2.Joueur) and (C.P1 = J3.Joueur))
        or  ((C.P3 = J1.Joueur) and (C.P1 = J2.Joueur) and (C.P2 = J3.Joueur))
        )
where (F.IsTeam = 1) 
    and (F.NbrJoueurs = 6) 
    and (J1.Team = J2.Team) 
    and (J2.Team = J3.Team) 
    and (J1.Win = 1) 
    and (J2.Win = 1)
    and (J3.Win = 1)
group by C.P1,C.P2, C.P3

返回的结果不完整且不正确:

Joueur1   Joueur2   Joueur3  Twin      Pwin
NULL      NULL      NULL      4      160
Charles   Mathieu   Thomas    1      40

返回的结果应该是:

Joueur1   Joueur2   Joueur3  Twin      Pwin
Mathieu   Francois  Bastien   1      40
Valery    Thomas    Charles   1      40
Charles   Mathieu   Thomas    2      80
Bastien   Valery    Francois  1      40

显然,问题来自于LEFT JOIN可能的3v3团队组合视图。它应该为各种团队组合做出正确的联合,玩家的顺序不同:

    left join VIEW_Equipes_Combinaisons_3 C 
        on (
            ((C.P1 = J1.Joueur) and (C.P2 = J2.Joueur) and (C.P3 = J3.Joueur)) 
        or  ((C.P2 = J1.Joueur) and (C.P3 = J2.Joueur) and (C.P1 = J3.Joueur))
        or  ((C.P3 = J1.Joueur) and (C.P1 = J2.Joueur) and (C.P2 = J3.Joueur))
        )

我无法理解为什么这不起作用。

如果你读到那里并试图理解,我已经祝贺并感谢你了: - )

问题很复杂,不易总结。我试图保持简短,而且已经足够长了。如果您没有足够的数据来理解问题(例如所有相关表的完整结构和每个表的数据样本,我可以提供它,但它会非常长。

编辑: 尝试将所有WHERE语句移动到各自JOIN的ON中,但这会给我相同的结果:

select C.P1 AS Joueur1, C.P2 AS Joueur2, C.P3 AS Joueur3, count(0) AS Twin, sum(P.Win) AS Pwin 
from MTG_Matchs M 
    join MTG_Matchs_Formats F on ((M.Format = F.Format) AND (F.IsTeam = 1) and (F.NbrJoueurs = 6))
    join VIEW_Matchs_Formats_Points P on  P.Format = F.Format
    left join MTG_Matchs_Joueurs J1 on ((J1.MatchID = M.ID) and (J1.Num = 1) and (J1.Win = 1))
    left join MTG_Matchs_Joueurs J2 on ((J2.MatchID = M.ID) and (J2.Num = 2) and (J2.Win = 1) AND (J1.Team = J2.Team))
    left join MTG_Matchs_Joueurs J3 on ((J3.MatchID = M.ID) and (J3.Num = 3) and (J2.Win = 1) AND (J2.Team = J3.Team) )
    left join VIEW_Equipes_Combinaisons_3 C 
        on (
            ((C.P1 = J1.Joueur) and (C.P2 = J2.Joueur) and (C.P3 = J3.Joueur)) 
        or  ((C.P2 = J1.Joueur) and (C.P3 = J2.Joueur) and (C.P1 = J3.Joueur))
        or  ((C.P3 = J1.Joueur) and (C.P1 = J2.Joueur) and (C.P2 = J3.Joueur))
        )  
group by C.P1,C.P2, C.P3

1 个答案:

答案 0 :(得分:0)

将右表条件从WHERE分别移动到ON。