选择和加入这些表的最有效方法

时间:2016-08-17 19:01:30

标签: sql

我有4张桌子:

表1(组):

id_group  name_group
1         abc
2         def
3         ghi

表2(彩色):

id_color  name_color
1         blue
2         red
3         green

表3(品种):

id_variety id_color id_group name_variety
1          1        1        light
2          3        1        dark
3          6        2        dark

表4(音):

id_tone id_color id_group name_tone
1          1      1       ocean
2          5      1       sea
3          9      3       clay

给定一个类似于1的id_group,我想做出一个像这样的选择:

id_group id_color name_variety name_tone
1        1        light        ocean
1        3        dark         NULL
1        5        NULL         sea

我能够通过联合解决问题并改变JOINS的顺序,但我认为必须有另一种解决方案

SELECT 
    GRO.id_group, COL.id_color, VARI.name_variety, TONE.name_tone
FROM 
    groups GRO
LEFT OUTER JOIN 
    variety VARI ON  (VARI.id_group = GRO.id_group) 
LEFT OUTER JOIN 
    tone TONE ON (TONE.id_group = GRO.id_group) 
              AND (TONE.id_color = VARI.id_color)
LEFT OUTER JOIN 
    color COL ON (COL.id_color = VARI.id_color) 
              OR (COL.id_color = TONE.id_color)
WHERE 
    GRO.id_group = 1

UNION

SELECT 
    GRO.id_group, COL.id_color, VARI.name_variety, TONE.name_tone
FROM 
    groups GRO
LEFT OUTER JOIN 
    tone TONE ON (TONE.id_group = GRO.id_group)
LEFT OUTER JOIN 
    variety VARI ON  (VARI.id_group = GRO.id_group) 
                 AND (VARI .id_color = TONE.id_color)
LEFT OUTER JOIN 
    color COL ON (COL.id_color = VARI.id_color) 
              OR (COL.id_color = TONE.id_color)
WHERE 
    GRO.id_group = 1

2 个答案:

答案 0 :(得分:0)

我认为你想要的更像是:

SELECT
    id_group,
    id_color,
    MAX(max_variety),
    MAX(max_tone)
FROM
    (SELECT 
        v.id_group, 
        v.id_color, 
        MAX(name_variety) AS max_variety, 
        MAX(name_tone) AS max_tone
    FROM 
        variety V   INNER JOIN 
        color c ON 
        V.id_color = c.id_color LEFT OUTER JOIN 
        tone t ON 
        t.id_group = v.id_group AND
        t.id_color = V.id_color
    WHERE 
        v.id_group = 1
    GROUP BY
        v.id_group, 
        v.id_color

    UNION ALL

    SELECT 
        t.id_group, 
        t.id_color, 
        MAX(name_variety) AS max_variety, 
        MAX(name_tone) AS max_tone
    FROM 
        tone t  INNER JOIN 
        color c ON 
        t.id_color = c.id_color LEFT OUTER JOIN 
        variety V ON 
        v.id_group = t.id_group AND
        v.id_color = t.id_color
    WHERE 
        t.id_group = 1
    GROUP BY
        t.id_group, 
        t.id_color) u
GROUP BY
    id_group,
    id_color

答案 1 :(得分:0)

而不是使用union,你可以使用完全连接,因为完全连接返回第一个表的所有结果以及第二个表的所有结果。

选择     来自Variety VARI的GRO.id_group,COL.id_color,VARI.name_variety,Tone.name_tone     在col.id_color = VARI col.id上连接Color COL      在GRO.id_group = VARI.id_group上加入GRO组      Tone.id_group = GRO.id_group上的完全连接音      其中GRO.id_group = 1