从多个LEFT JOIN获取不同的行

时间:2015-08-02 17:33:57

标签: mysql left-join distinct

这是我的match

+----------------------------+
|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    |
+------------------+

然后是players

+----------------------+
|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    |
+------------------------+

谢谢;)

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

这是一个非常重要的结果。我更喜欢使用两个单独的语句来获取两个单独的团队列表,并在客户端中一起处理两个结果的格式化,而不是使用单个SQL语句。

但是,如果我必须使用单个SQL语句生成此结果,我会这样做,使用内联视图,使用用户定义的变量为每个团队列表生成“行号”值...两个团队列表使用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

答案 2 :(得分:0)

req.getRequestDispatcher("ManufacturerDetails.jsp").forward(req, resp);

结果

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