2014-01-22 38 views
0

OK,所以這裏的(很簡單)表我感興趣的是:如何使這個語法更好?

|===================== 
| objects 
|===================== 
| id | name 
| 

|===================== 
| properties 
|===================== 
| id | name 
| 

|==================================================== 
| object_properties 
|==================================================== 
| id | object_id | property_id | value 
| 

我需要做的是:

  • 基於一個對象名字
  • 抓取所有屬性名稱 - 值對

這是我的SQL(其中,ac Tually取得相當一切):

SELECT * 
FROM objects, properties, object_properties 
WHERE 
     objects.name="SOME_VALUE" AND 
     object_properties.object_id = objects.id AND 
     object_properties.property_id = properties.id 

它看起來不錯嗎?我究竟做錯了什麼?我知道我的SQL技能接近於不存在,所以我願意提供建議!


P.S.鑑於實際的查詢將在巨大的數據集上執行,什麼是最有效的解決方案?

+0

正在使用'joins'不是一個選項? –

+0

第一件事,根據你的表'objects.value'不存在 –

+0

Ummm,objects.value不存在?它不在對象表中。 –

回答

1

推薦的ANSI SQL-92語法是使用JOINS。

SELECT p.name,op.value 
FROM objects o 
INNER JOIN object_properties op 
    ON o.id=op.object_id 
INNER JOIN properties p 
    ON p.id=op.property_id 

WHERE o.value="SOME_VALUE" 

你在做什麼也是實現連接,但有一個缺點。 假設在涉及多個表的大查詢中,您錯過了WHERE子句中的加入條件。查詢仍然可以成功執行,因爲沒有連接條件,SQL將在兩個表之間執行笛卡爾乘積並返回超過正確數量的行。

但是,如果您使用明確提到的關鍵字JOIN進行連接,如果您錯過了ON子句後指定的連接條件,則查詢將從調試中拋出語法錯誤,以防止錯誤返回的結果集。

+0

嗯,我猜它看起來不錯。不知道爲什麼,但我總是傾向於避免使用「加入」,就好像一些可怕的事情會發生一樣......哈哈。謝了哥們! –

+0

表現如何?如果我們需要專注於優化大數據集上的速度,有什麼辦法可以做到上述查詢? –

+0

有關優化,請參閱索引 - http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html –

1
select properties.name, object_properties.value 
    from objects 
where objects.name = "SOME_VALUE" 
    and object_properties.object_id = objects.id 
    and properties.id = object_properties.property_id 

由於您想要屬性名稱和對象屬性值,這些是我的選擇列表中唯一的字段。

由於您的關鍵字是對象名稱,因此這是在對象的名稱上引入過濾器的起點。

從感興趣的實際對象中,沿着鏈通過相關表。由於對象只與object_properties相關,因此從該連接開始。該連接立即使值可用。需要再次加入才能獲取該屬性的名稱。通過將對象屬性行連接到適當的屬性行,使您可以訪問屬性名稱。

順便說一下,此語法是「舊式」SQL,其中連接和過濾器被混合到一個WHERE子句中。現代風格爲了清晰起見將它們分開,我相信你會得到一些回覆,顯示更現代的語法;-)