2009-08-14 79 views
1

我有一個表爲其他表的entrys保存元數據。元數據表看起來像這樣(我刪除與ID,以便它更明顯):MySQL:多次搜索單個表?

id entry_id property value
1 12 color blue
2 12 shape circle
3 13 color red
4 13 shape circle
5 14 color blue
6 14 shape square
7 15 material stone
8 12 material plastic

現在我要搜索此表的屬性,如選擇所有條目,其中顏色藍色

select entry_id from table where property = 'color' and value = 'blue'

到目前爲止,一切都很好。但是,如何在有多個條件時擴展查詢?例如,我想搜索所有條目,其中顏色藍色形狀圈子。現在我想與工會實現這一目標:

select entry_id from table where property = 'color' and value = 'blue'
union
select entry_id from table where property = 'shape' and value = 'circle'

這顯然變得醜陋了更多的屬性我想看看。我認爲這也不是很快。有沒有更優雅的方式來做到這一點?這張表的原因是,我有對象與元數據可以由用戶設置。

謝謝!

+0

要獲得godd的性能,不管你採取什麼解決方案,你必須創建一個索引(entry_id,property,value)。如果這個三元組不是主鍵。 – 2009-08-14 13:53:44

回答

1

這是你在找什麼?

select 
    distinct e1.entry_id 
from 
table e1 
inner join 
    table e2 on e1.entry_id=e2.entry_id 
where 
    e1.property='color' and 
    e1.value='blue' and 
    e2.property='shape' and 
    e2.value='circle' 
+0

我會選擇DISTINCT entry_id的 – Martijn 2009-08-14 13:13:16

+0

您需要做的選擇不同,ID 12會回來兩次,他的聯合聲明是放棄重複。 – Andrew 2009-08-14 13:13:29

+0

我修改它,所以它會選擇他要求的不是他以前的查詢返回(希望這是他想要的) – 2009-08-14 13:16:53

0
SELECT a.entry_id 
FROM table a INNER JOIN table b USING (entry_id) 
WHERE a.property = 'color' AND a.value = 'blue' 
    AND b.property = 'shape' AND b.value = 'circle' 
+0

謝謝,這是否表現良好? – acme 2009-08-14 13:42:27

+0

@acme要獲得godd的性能,您必須在(entry_id,property,value)上創建一個索引。如果這個三元組不是主鍵。 – 2009-08-14 13:52:45

0

你就可以欺騙MySQL來代替unionor建立一個哈希表:

select distinct 
    entry_id 
from 
    table t 
    inner join 
     (select 'shape' as property, 'circle' as value 
     union all 
     select 'color' as property, 'blue' as value) s on 
     t.property = s.property 
     and t.value = s.value 

您也可以嘗試exists:中

select distinct 
    entry_id 
from 
    table t 
where 
    exists (select 1 from 
       (select 'shape' as property, 'circle' as value 
       union all 
       select 'color' as property, 'blue' as value) s 
      where 
       s.property = t.property 
       and s.value = t.value) 

使用一個這兩種方法,你可以追加儘可能多的搜索條件,因爲你的小心臟需要簡單地加上另一個union alls子查詢。

+0

謝謝,我可以期待任何性能問題嗎? – acme 2009-08-14 13:43:12

+0

以及如何使用這些方法在字段上實現「類似」搜索? – acme 2009-08-14 13:54:50

+0

這些應該是非常高效的。至於'like',如果你覺得這樣傾向的話,你可以't.property'如'%'+ s.property +'%''。這只是一個連接條件,所以如果你需要的話,堅持下去。 – Eric 2009-08-14 14:22:33