2009-07-20 93 views
1

我想知道將LEFT JOIN轉換爲表格/矩陣的好方法。從SQL中的LEFT JOIN創建一個矩陣/表格

例如,假設這個模式:

 
objects 
    id (integer) 
    name (string) 

attributes 
    id (integer) 
    object_id (integer) 
    name (string) 
    value (string) 

這些值:

 
1,ball 
2,box 

1,1,colour,red 
2,1,shape,sphere 
3,1,material,rubber 
4,2,colour,brown 
5,2,shape,cube 

我希望得到這樣的:

 
object_id | object_name | colour | shape | material 

1   | ball  | red | sphere | rubber 
2   | box   | brown | cube | NULL 

理想的情況下,這將是與每個對象的屬性數量未知,並且適用於不使用存儲過程的MySQL。

回答

1

RDBMS s的事情是他們的目的是存儲和呈現你已有的東西。動態創建列從未打算。

這是一個應該在呈現數據的客戶端上處理的情況。

無視RDBMS應該如何使用,您仍然不會找到一個簡單的方法來做到這一點。尤其是,如果你想列列表是動態的。您可以構建一個動態SQL查詢並執行該查詢,但無法編寫標準SQL查詢並獲得該結果(因爲您始終明確指定所有列,所以使用*,但在這種情況下無法用於您的優勢case)。

1

如果不在SQL中使用動態查詢,則無法執行此操作。

任何設置SQL處理假定列數固定,固定名稱。

否則會導致很多事情SQL只是沒有設計來處理。

一樣,想象你要求的查詢創建一個視圖(均可能):

SELECT object_id, colour 
FROM myquery 

不管這種觀點彙總與否將取決於查詢的結果,這將讓你運行時錯誤(這很難處理),而不僅僅是空的結果集(這很容易處理)。

你基本上是在談論這裏的結果展示,而這些東西都是在客戶端上專門完成的。

如果你有attribute_names表,其中包含您屬性的所有可能的名字,你可以做這樣的事情:

SELECT o.name, an.name, a.value 
FROM objects o 
CROSS JOIN 
     attribute_names an 
LEFT JOIN 
     attributes a 
ON  a.object = o.id 
     AND a.name = an.name 

,其中將包含所有可能的object_id/attribute_name對與相應的值,你可以用它客戶端更容易填充矩陣。

0

這會解決你的問題,假設結果表被稱爲合併,雖然你有我說的架構更好。

insert into merged (object_id, object_name) select id, name from objects; 
update merged m inner join attributes a on a.object_id = m.object_id and a.name = 'colour' set m.colour = a.value; 
update merged m inner join attributes a on a.object_id = m.object_id and a.name = 'material' set m.material = a.value; 
update merged m inner join attributes a on a.object_id = m.object_id and a.name = 'shape' set m.shape = a.value; 
0

嗯,這是可能的,你只是缺少2個邏輯步驟,使這種情況發生。

你需要的是一個AttributeTypes表和AttributeValues表。

objects 
    id (integer) 
    name (string) 

attribute_types 
    id (integer) 
    name (string) 
    description (string) 
    enabled (bit) 

attribute_values 
    id (integer) 
    attribute_type_id (integer) 
    value (string) 
    enabled (bit) 

attributes 
    id (integer) 
    object_id (integer) 
    attribute_type_id (integer) 
    attribute_value_id (integer) 

因此,一個對象可以有屬性,這些屬性由attribute_type_id和attribute_value_id指定。

這就可以讓你有多個屬性的對象..

object 
-> 1, ball 

attribute_types 
-> 10, Colour, null, enabled 
-> 20, Shape, null, enabled 
-> 30, Material, null, enabled 

attribute_values 
-> 100, 10, blue, enabled 
-> 200, 10, red, enabled 
-> 300, 10, green, enabled 

-> 400, 20, round, enabled 
-> 500, 20, square, enabled 
-> 600, 20, triangle, enabled 

所以一個屬性會是什麼樣子:

attributes 
-> 1000, 1, 10, 100 // this item has a color and it is blue 
-> 1001, 1, 20, 400 // this item has a shape and it is round 
-> 1002, 1, 10, 200 // this item has a color and it is red 

所以現在對象可以有多個屬性它們在不同的表格中指定它們的值。現在重要的問題是如何查詢這個問題的?您可能需要拆分取決於你的SQL是多麼強大的查詢分爲多個部分。

@attribute_type_id = select Id from attribute_types where name = 'Color' // 10 

select * from objects 
inner join attributes on objects.id = attributes.object_id 
inner join attribute_values on objects.attribute_value_id = attribute_values.id 
where attribute_type_id = @attribute_type_id 
and attribute_values.value= 'blue' 

在那裏,你應該帶回每一個對象,它的屬性類型爲Color,屬性值爲藍色。

我的SQL是不是強大,但你應該能夠做到以上的條款,如果你想搜索在同一時間多個屬性。在我的腦海中屬性表attribute_type_id未加入到attribute_type表,但它可以方便的一重擊做了查詢,性能方面雖然I'de擁有它,所以它會加快查詢通過不加入表但差異可能因一切有多大變得可以忽略不計。

注:我通常與msssql工作,而不是在mysql因此,如果數據庫類型不匹配,這就是爲什麼。