从多个 LEFT JOIN 中获取不同的行

Get distinct rows from multiple LEFT JOIN

这是我的matchtable

+----------------------------+
|Match_id |team1_id|team2_id |
------------------------------
|    1    |   1    |    2    |
+----------------------------+

球队有几场比赛由team_player

映射
+------------------+
|team_id |player_id|
--------------------
|    1    |   1    |
|    1    |   2    |
|    1    |   3    |
|    2    |   4    |
|    2    |   5    |
|    2    |   6    |
+------------------+

然后是playerstable

+----------------------+
|player_id |player_name|
-----------------------|
|    1     |   p1      |
|    2     |   p2      |
|    3     |   p3      |
|    4     |   p4      |
|    5     |   p5      |
|    6     |   p6      |
+----------------------+

我尝试按球队获取球员姓名。这是我的查询:

SELECT tp1.`player_id` as id1, tp2.`player_id` as id2, p1.`player_name` as pseudo1, p2.`player_name` as pseudo2
FROM (`match` m
LEFT JOIN `team_player` tp1 ON m.`team1_id` = tp1.`team_id`
LEFT JOIN `team_player` tp2 ON m.`team2_id` = tp2.`team_id`)
LEFT JOIN `players` p1 ON tp1.`player_id` = p1.`player_id`
LEFT JOIN `players` p2 ON tp2.`player_id` = p2.`player_id`
WHERE m.`MATCH_ID`= 49

它让我明白了:

+------------------------+
|id1 |id2|pseudo1|pseudo2|
|------------------------|
|1   |4  |   p1  | p4    |
|1   |5  |   p1  | p5    |
|1   |6  |   p1  | p6    |
|2   |4  |   p2  | p4    |
|2   |5  |   p2  | p5    |
|2   |6  |   p2  | p6    |
|3   |4  |   p3  | p4    |
|3   |5  |   p3  | p5    |
|3   |6  |   p3  | p6    |
+------------------------+

是否可以得到这个:

+------------------------+
|id1 |id2|pseudo1|pseudo2|
|------------------------|
|1   |4  |   p1  | p4    |
|3   |5  |   p2  | p5    |
|1   |6  |   p3  | p6    |
+------------------------+

谢谢 ;)

您应该只加入 'team_player' 一次,例如

tp ON  tp.`team_id` in (m.`team1_id`, m.`team2_id`)

这是一个不平凡的结果。我宁愿使用两个单独的语句来获取两个单独的团队列表,并在客户端中一起处理两个结果的格式,而不是使用单个 SQL 语句。

但是,如果我必须使用单个 SQL 语句生成此结果,我会这样做,使用内联视图,使用用户定义的变量生成 "row number" 值每个团队列表...将两个团队列表与 UNION ALL 组合,并使用 GROUP BY 行号组合行,并使用 SELECT 列表中的条件来挑选 team1 和 team2 的值列。

   SELECT MAX(IF(s.tn='1',s.id    ,NULL)) AS id1
        , MAX(IF(s.tn='2',s.id    ,NULL)) AS id2
        , MAX(IF(s.tn='1',s.pseudo,NULL)) AS pseudo1
        , MAX(IF(s.tn='2',s.pseudo,NULL)) AS pseudo2
     FROM ( 
            ( SELECT @rn1 := @rn1 + 1 AS rn
                   , '1'              AS tn
                   , tp1.player_id    AS id
                   , p1.player_name   AS pseudo
                FROM (SELECT @rn1 := 0 ) i1 
                JOIN `match` m1 ON m1.match_id   = 49
                JOIN team_player tp1 ON tp1.team_id = m1.team1_id
                LEFT JOIN players p1 ON p1.player_id = tp1.player_id 
               ORDER BY p1.player_id
            )  
            UNION ALL    
            ( SELECT @rn2 := @rn2 + 1 AS rn
                   , '2'              AS tn
                   , tp2.player_id    AS id
                   , p2.player_name   AS pseudo
                FROM (SELECT @rn2 := 0 ) i2 
                JOIN `match` m2 ON m2.match_id   = 49
                JOIN team_player tp2 ON tp2.team_id = m2.team2_id
                LEFT JOIN players p2 ON p2.player_id = tp2.player_id 
               ORDER BY p2.player_id
            ) 
          ) s
    GROUP BY s.rn
    ORDER BY s.rn

SQL Fiddle demomonstration here: http://sqlfiddle.com/#!9/61dd4/2

select id1, id2, pseudo1, pseudo2
  from
    (select @n:=@n+1 n, tp.player_id id1, player_name pseudo1 
       from 
         (select @n:=0) n, 
         (`team_player`tp 
            join `players` p 
              on p.`player_id` = tp.`player_id`)
      where team_id = 
         (select team1_id from `match` where Match_id = 49)) as sel1 
   join 
    (select @m:=@m+1 m, tp.player_id id2, player_name pseudo2 
       from 
         (select @m:=0) m, 
         (`team_player`tp
             join `players` p 
               on p.`player_id` = tp.`player_id`)
       where team_id = 
          (select team2_id from `match` where Match_id = 49)) sel2
   on n = m

结果

id1  id2  pseudo1  pseudo2
1    4    p1       p4
2    5    p2       p5
3    6    p3       p6