2009-08-14 5 views
1

私は別のテーブルからのエントリのメタデータを保持しているテーブルを持っています。MySQL:1つのテーブルを複数回検索していますか?

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

今、私はあるすべてのエントリを選択するように、性質のため、このテーブルを検索したい:メタデータ表には、この(私はそれがより明白ですので、Idsは関係削除)のように見えます:

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 performaceを取得するには、どの解決策をとっても問題がありません。(entry_id、property、value)にインデックスを作成する必要があります。このトリプルがすでに主キーでない場合。 –

答えて

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

+0

を選択すると、あなたは別の選択をする必要があります。ID 12は2回戻ってくるでしょう、彼のユニオンステートメントは重複を破棄しています。 – Andrew

+0

私はそれを変更して、前回のクエリが返されたものではないことを彼が求めたものを選択しました(これが彼が望むものであることを望みます) –

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

+0

@acme godd performaceを取得するには、(entry_id、property、value)にインデックスを作成する必要があります。このトリプルがすでに主キーでない場合。 –

0

あなたはunionまたはorの代わりにハッシュテーブルを構築するにMySQLをだますことができます。

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) 

のいずれかを使用してこれらの2つの方法は、あなたの小さな心の欲望と同じくらい多くの検索条件を別のunion allからsサブクエリに単にタックします。

+0

ありがとう、私は期待できる性能問題はありますか? – acme

+0

と私はどのようにこれらのmeethodsでフィールドの "好きな"検索を達成することができますか? – acme

+0

これらは実際には非常に優れているはずです。 'like'に関しては、'% '+ s.property +'% ''のようなt.propertyが好きなら、あなたはそうすることができます。これは単なる結合条件なので、必要に応じてそれを使ってナットを実行します。 – Eric

関連する問題