2012-10-03 47 views
0

我在这里得到的问题可能看起来很愚蠢,但是这让我有点疯狂,因为我无法得到MySQL连接的工作方式。MySQL:如何组合从另一个表中多次引用的列并分配正确的别名?

我有2个表:

user; 
+--------------------+--------------+------+-----+---------+-------+ 
| Field    | Type   | Null | Key | Default | Extra | 
+--------------------+--------------+------+-----+---------+-------+ 
| id     | int(11)  | NO | PRI | NULL |  | 
| name    | varchar(128) | NO |  | NULL |  | 
+--------------------+--------------+------+-----+---------+-------+ 

game; 
+--------------------+--------------+------+-----+---------+-------+ 
| Field    | Type   | Null | Key | Default | Extra | 
+--------------------+--------------+------+-----+---------+-------+ 
| id     | int(11)  | NO | PRI | NULL |  | 
| source_id*   | int(11)  | NO |  | NULL |  | 
| target_id*   | int(11)  | NO |  | NULL |  | 
+--------------------+--------------+------+-----+---------+-------+ 

game.source_idgame.target_id是引用该user.id约束。

现在我想选择game表中的所有内容,并且我想包含2个用户的结果名称,因为game有2个用户。我希望这些列的名称具体为target_namesource_name

尝试这样的查询

SELECT 
    g.id, 
    u.name 
FROM 
    game g 
RIGHT JOIN 
    user u 
ON 
    u.id = g.source_id 
OR 
    u.id = g.target_id 
WHERE 
    g.source_id = 1 
OR 
    g.target_id = 1 
; 

但正如你可能已经注意到,我没有别名u.nametarget_namesource_name,因为我不知道该怎么做,最终的结果看起来是这样的:

+----+------+ 
| id | name | 
+----+------+ 
| 1 | bo | 
| 1 | al | 
| 2 | jo | 
| 2 | jay | 
+----+------+ 

正如你所看到的,在结果中出现了多个game

预期的结果:

+----+-------------+-------------+ 
| id | target_name | source_name | 
+----+-------------+-------------+ 
| 1 | bo   | al   | 
| 2 | jo   | jay   | 
+----+-------------+-------------+ 

在此先感谢。

回答

1

你需要加入表user两次表game为了获得游戏的两个名字。我添加了COALESCE,因为它对于显示NULL列的描述性值很有用。例如,如果源或目标没有值,则将显示的值为“-no value-”。

SELECT a.*, 
     COALESCE(b.name,'-no source-') sourceName, 
     COALESCE(c.name,'-no target-') targetName 
FROM game a 
     LEFT JOIN `user` b 
      on b.id = a.source_ID 
     LEFT JOIN `user` c 
      on on c.id = a.target_id 
-- your condition here 
+0

谢谢。这也起作用。这是否意味着每次连接都会通过'用户表'运行两次? –

+1

是的,但它会很快,因为定义该关系的那些键已经是索引。 –

+0

感谢您对COALESCE的额外信息。但是,如果我添加了'WHERE'子句,那么我不需要它(“COALESCE”),因为如果没有'source_id'或'target_id',游戏就无法存在? –

1
SELECT 
    g.id, 
    source.name, 
    target.name 
FROM 
    game g 
LEFT JOIN 
    user source 
ON 
    source.id = g.source_id 
LEFT JOIN 
    user target 
ON 
    target.id = g.target_id 
WHERE 
    g.source_id = 1 
OR 
    g.target_id = 1 
; 

where子句是可选的,并且意在由搜索用户ID = 1玩过的所有游戏,如源或作为靶。

+0

谢谢。它完成这项工作,我可以别名'source.name'和'target.name'。感谢您指出WHERE子句。在最终的应用程序中,我需要它,因为这正是我需要做的 - 为特定用户获取所有游戏。 –

相关问题