2011-10-03 138 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.成分和顏色表是唯一的一對多糖果關係。不過謝謝。你給了我一些要思考的東西,不管怎樣。 –