MySQL: 如何在同一张表中多次进行连接?

56

我有两个表ticketattr。表ticketticked_id字段和其他几个字段。表attr有3个字段:

ticket_id - numeric
attr_type - numeric
attr_val - string

attr_type是一个固定的枚举值。例如,它可以是123

我需要进行一个查询,其结果将包含4列:

ticket_id,对于attr_type=1attr_val,对于attr_type=2attr_val,对于attr_type=3attr_val

如果在attr表中没有对应的attr_type值,则相应列应显示NULL值。

ticket表:

ticket_id
1
2
3

attr表:

票务ID 属性类型 属性值
1 1 Foo
1 2 Bar
1 3 Egg
2 2 Spam

预期输出:

ticket_id attr_val1 attr_val2 attr_val3
1 Foo Bar Egg
2 null Spam null
3 null null null

我尝试了三次左连接attr表,但无法弄清如何按attr_type排列输出。

3个回答

85

你需要使用多个 LEFT JOIN

SELECT 
    ticket.ticket_id,  
    a1.attr_val AS attr_val1,
    a2.attr_val AS attr_val2,
    a3.attr_val AS attr_val3
FROM ticket
    LEFT JOIN attr a1 ON ticket.ticket_id=a1.ticket_id AND a1.attr_type=1
    LEFT JOIN attr a2 ON ticket.ticket_id=a2.ticket_id AND a2.attr_type=2
    LEFT JOIN attr a3 ON ticket.ticket_id=a3.ticket_id AND a3.attr_type=3

以下是一个示例:SQL Fiddle


我在我的类似问题中尝试了您的查询,但它返回了相同的记录。为什么会这样?我错在哪里了? - rahim.nagori

13

虽然你可以使用别名左连接,但在这种情况下,你也可以使用分组和条件表达式的组合:

select t.ticket_id,
       max(case when a.attr_type=1 then a.attr_val end) attr_val1,
       max(case when a.attr_type=2 then a.attr_val end) attr_val2,
       max(case when a.attr_type=3 then a.attr_val end) attr_val3
from ticket t
left join attr a on t.ticket_id = a.ticket_id
group by t.ticket_id

11
您使用了表别名。
例如:
Select 
    ticket.ticket_id,  
    a1.attr_val as attr_val1,
    a2.attr_val as attr_val2,
    a3.attr_val as attr_val3
from ticket
    left join (select * from attr where attr_type=1) a1 on ticket.ticket_id=a1.ticket_id
    left join (select * from attr where attr_type=2) a2 on ticket.ticket_id=a2.ticket_id
    left join (select * from attr where attr_type=3) a3 on ticket.ticket_id=a3.ticket_id

这对我来说效果最好,因为我必须在我想要进行LEFT JOIN的表上执行INNER JOIN。 - Alan Stewart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接