MySQL多列连接有多个表引用

时间:2015-03-12 11:24:55

标签: mysql sql join

我正在使用MySQL 5.6.17

我有table包含标题的主条目,让我们说出Master_titles。它包含列id int primary key auto-incrementtitle varchar(255)。数据如下所示:

id     title
1      Item one
2      Item two
3      Item three
4      Item five 
6      Item six
7      Item seven
8      Item eight
9      Item nine
10     Item ten

另一个名为routines的表self-referencing table包含records with parent-child relationship。列是id int primary key auto-incrementmaster_title_id int foreign key references id of Master_titlestype varchar(2)parent int foreign key referencing id of routines本身。数据如下:

id     master_title_id     type     parent 
1      1                   G        null
2      2                   Q        1
3      3                   A        2
4      4                   A        2 
5      5                   Q        1
6      6                   A        5
7      8                   A        5
8      2                   G        null 
9      5                   Q        8
10     7                   A        9
11     8                   A        9
12     9                   A        9

另一张表让我们说data,其中包含id int primary key auto-incrementroutine_id int foreign key references id of routinesgroup id intquestion_id intanswer id int等列。此处,列的所有记录,即group_idquestion_idanswer_id将是id表的routines。数据如下:

id     routine_id     group_id     question_id     answer_id
1      2              1            2               4
2      5              1            5               6
3      9              8            9               11
4      5              1            5               7
5      2              1            2               7
3      9              8            9               10

现在,我想要querytitles表中为group_idquestion_idanswer_id列提取master_titles

我可以使用sub-query来做,但是什么是最有效的方法来获取记录而没有开销?

查询即工作但我不喜欢使用如下:

SELECT  data.created_at,
(SELECT Master_titles.title FROM `Master_titles` LEFT JOIN routines ON Master_titles.id = routines.master_title_id LEFT JOIN data ON routines.id = data.group_id WHERE data.id = data.`id`) AS Group,
(SELECT Master_titles.title FROM `Master_titles` LEFT JOIN routines ON Master_titles.id = routines.master_title_id LEFT JOIN data ON routines.id = data.question_id WHERE data.id = data.`id`) AS Question,
(SELECT Master_titles.title FROM `Master_titles` LEFT JOIN routines ON Master_titles.id = routines.master_title_id LEFT JOIN data ON routines.id = data.answer_id WHERE data.id = data.`id`) AS Answer
FROM data;

3 个答案:

答案 0 :(得分:2)

根据您的评论说明,表data中包含ID的所有列实际上都是ids routines表,您需要通过执行连接来获取每列的标题路径为routines > master_titles

SELECT 
    d.id,
    d.routine_id,
    mgroup.title group,
    mquestion.title question,
    manswer.title answer
FROM
    data d
    LEFT JOIN routines r1 ON ( d.group_id = r.id )
    LEFT JOIN master_titles mgroup ON ( r1.master_title_id = m.id )
    LEFT JOIN routines r2 ON ( d.question_id = r.id )
    LEFT JOIN master_titles mquestion ON ( r2.master_title_id = m.id )
    LEFT JOIN routines r3 ON ( d.answer_id = r.id )
    LEFT JOIN master_titles manswer ON ( r3.master_title_id = m.id )

不要担心连接数量(从不按行数计算查询成本)。

我建议跟随索引来加速:例程(master_title_id)。

另外,在group_id,question_id和answer_id列上考虑(无法估计您的环境)索引。

你最了解它是否能帮助你提高性能,同时不会无利可图地损害你的写作/空间。

答案 1 :(得分:1)

从“考虑我”回答中稍作改动。

SELECT 
    d.id,
    d.routine_id,
    mgroup.title group,
    mquestion.title question,
    manswer.title answer
FROM
    data d
    JOIN routines r1 ON ( d.group_id = r.id )
    JOIN master_titles mgroup ON ( r1.master_title_id = m.id )
    JOIN routines r2 ON ( d.question_id = r.id )
    JOIN master_titles mquestion ON ( r2.master_title_id = m.id )
    JOIN routines r3 ON ( d.answer_id = r.id )
    JOIN master_titles manswer ON ( r3.master_title_id = m.id )

内部联接应该更好,因为group_idquestion_idanswer_id未在data表中定义为可空。但由于没有外键关系,如果在例程表中没有值,则可能存在缺少行的实例。

答案 2 :(得分:-1)

您可以通过对正在连接的表进行别名来对同一个表执行多个连接。

SELECT data.id, gm.title AS gm_title, qm.title AS qm_title, am.title AS am_title 

JOIN routines AS gr
ON gr.id = data.group_id    
JOIN master_titles AS gm 
ON gm.id = gr.master_title_id 

JOIN routines AS qr
ON qr.id = data.question_id
JOIN master_titles AS qm
ON qm.id = qr.master_title_id

JOIN routines AS ar
ON ar.id = data.answer_id
JOIN master_titles AS am
ON am.id = ar.master_title_id

FROM data
相关问题