2011-10-03 237 views
0

我正在简化实际案例以便更快地获得要点,就像抬头看起来似乎无意义一样。跨多个表格的复杂查询

我有一张名为Candy_Central的表格。 Candy_Central拥有我糖果的所有ID,每磅的价格以及所有Candy记录中的其他重要信息。它也有一个名为Candy_Type的字段。 Candy_Type的价值可能是巧克力,坚硬,胶质或液体。

我有另一套表用于糖果信息,但他们的使用是由糖果类型决定的。例如,如果我想了解我的主要巧克力棒的其他信息,我需要去Chocolate_Standard以获取其余的信息。如果我在外面看糖胶蠕虫,我需要去Gummy_Standard。原因是一组信息的字段与另一组信息的字段完全不同。

我还有一层信息,颜色。我的糖果是蓝色的,我的糖果是黑色的,而且我有两种颜色的糖果。我目前存储这些信息的方式是,我有一个表格,其中的字段为Candy_IdColor。为了找到所有的颜色,我通常只需在这张桌子上使用color_id字段来查询我感兴趣的糖果。但是SQL当然是要找到所有的结果。所以如果我想找到所有的粘连信息,我想要做某种连接或联合。我不是非常熟悉这种类型的查询,所以我不知道如何获得我想要的结果表,这基本上会[对于psuedo查询] [来自Candy_Main的项目作为CM ...项目从Gummy as g ...颜色项目作为c ...其中cm.candy_id = g.candy_id和cm.candy_id = c.candy_id)。如果软糖没有颜色,我只想要null。我很满意为每个candy_id获取了多条线,但我希望尽可能有限,这样后处理(将多条糖果线变成我的应用程序中的一个对象)花费尽可能少的时间。

表:

Candy_Main 
    candy_id (primary key, auto increment, not null, etc) 
    candy_name (varchar) 
    candy_inventor_id (a primary key from some other table, but this is needed for the where clause. 
    candy_type (varchar) 

Gummy_Standard 
    gummy_id (primary, auto) 
    candy_id (should match to candy_main) 
    softness (varchar) 
    outer_coating_type (varchar) 
    animal_likeness (varchar) 

Gummy_Colors 
    gummy_color_id (primary, auto) 
    gummy_id (int) 
    candy_id (int) 
    color (varchar(64)) 

Gummy_Ingredients 
    gummy_ingredient_id (primary, auto) 
    gummy_id (int) 
    candy_id (int) 
    ingredient (varchar(64)) 

现在,我要为所有条目where candy_inventor_id = 5 AND candy_type = 'gummy'做一个查询。在查询结束时,我想要candy_name, candy_type, softness, outer_coating_type, animal_likeness, colors, and ingredients

颜色&成分是在这个查询中不是1对1的唯一对象,所以我希望那里只有尽可能多的条目,因为有颜色和成分。感谢您的帮助,如果这是可能的。我有一种感觉,即将颜色或成分限制在这个范围内会很容易,但这对于两者来说都太难了。

回答

1

试试这个

SELECT c.candy_name, c.candy_type, s.softness, s.outer_coating_type, 
     s.animal_likeness, 
     GROUP_CONCAT(gc.color), 
     GROUP_CONCAT(gi.ingredient) 
FROM candy_main c 
LEFT JOIN gummy_standard s on s.candy_id=c.candy_id 
LEFT JOIN gummy_colors gc on gc.candy_id = c.candy_id 
LEFT JOIN gummy_ingredients gi cl on cl.candy_id = c.candy_id 
WHERE c.candy_inventor_id=5 AND c.candy_type='gummy' 
GROUP BY gc.color , gi.ingredient 
+0

我结束了只有一行,其中所有的信息已被平摊。这就是说,GROUP_CONCAT看起来像是一个有希望进一步调查的方向。难道是GROUP_BY的缺席? –

+0

立即尝试@Brian。 – diEcho

+0

想通了。我输入了ORDER BY。我的错。谢谢,这会做。我在GROUP CONCAT列表中获得了一些复制,可能是因为使用了多个表格,我想将其除掉,但可以等待。非常感谢! –

1

如果我正确理解你的数据库的设置,对于每一个糖果,有很多潜在的gummy_standards(这么硬熊和巧克力熊可能是链接到一个糖果录制两个橡皮糖标准记录)。在这种情况下,下面应该工作:

SELECT cm.candy_name, cm.candy_type, gs.softness, gs.outer_coating_type, gs.animal_likeness, gc.color, gi.ingredient 
FROM Candy_Main cm 
    INNER JOIN Gummy_Standard gs ON gs.candy_id = cm.candy_id 
    INNER JOIN Gummy_Colors gc ON gc.candy_id = gs.gummy_id 
    INNER JOIN Gummy_Ingredients gi ON gi.gummy_id = gs.gummy_id 
WHERE candy_inventor_id = 1 -- Of course, this 1 be replaced with the actual inventor's ID 

记住,做这样会导致重复到多重交叉,因此,如果胶质有三种颜色和4种成分,重复所有三种颜色的每种成分(所以12条线只是一个胶粘)。如果你不想要这样做,可以尝试将字符串连接到一行,然后在代码中拆分该行。不知道是什么在MySQL的功能,但如果CONCAT_WS()就像textcat_all()一样的PostgreSQL,那么下面应该工作:在架构

SELECT cm.candy_name, cm.candy_type, gs.softness, gs.outer_coating_type, gs.animal_likeness, CONCAT_WS(', ', gc.color), CONCAT_WS(', ', gi.ingredient) 
FROM Candy_Main cm 
    INNER JOIN Gummy_Standard gs ON gs.candy_id = cm.candy_id 
    INNER JOIN Gummy_Colors gc ON gc.candy_id = gs.gummy_id 
    INNER JOIN Gummy_Ingredients gi ON gi.gummy_id = gs.gummy_id 
WHERE candy_inventor_id = 1 -- Of course, this 1 be replaced with the actual inventor's ID 
GROUP BY cm.candy_name, cm.candy_type, gs.softness, gs.outer_coating_type, gs.animal_likeness 

两个小技巧:
1.如果我对表格的理解是正确的,成分和颜色总是适用于胶粘标准记录,然后颜色和配料中的candy_id字段是多余的。最好每次都通过Gummy Standard连接到Candy。
2.您可能受益于更高程度的规范化,即创建颜色表和成分表,然后链接到这些表,而不是像原样那样在表中包含字符串描述。这样可以更轻松地对所有适当的记录进行更改,例如,由于您添加了蓝色(浅色),因此您要更改蓝色的名称为蓝色(黑色),您只需更新一条记录,而不是所有的彩色记录都表示蓝色(或者蓝色,或者因为拼写错误经常发生,所以每次都必须输入相同的描述)。所以你的表看起来像:

Color 
    color_id (primary, auto) 
    color (varchar(64)) 

Ingredient 
    ingredient_id (primary, auto) 
    ingredient (varchar(64)) 

Gummy_Colors 
    gummy_color_id (primary, auto) 
    gummy_id (int) 
    candy_id (int) 
    color_id (foreign key to Color) 

Gummy_Ingredients 
    gummy_ingredient_id (primary, auto) 
    gummy_id (int) 
    candy_id (int) 
    ingredient_id (foreign key to Ingredient) 

希望这有助于。

+0

它的确如此,我想我现在要查找外键。 :)。不幸的是,我没有把介绍打好。 cm&gs应该是1比1.成分和颜色表是唯一的一对多糖果关系。不过谢谢。你给了我一些要思考的东西,不管怎样。 –