1

SQLite で、特定のプロパティ + 値を持つ記事、または特定のプロパティを持たない記事 (プロパティが別のテーブルにある) を検索するための SELECT クエリを作成したいと考えています。

これは、私が持っているデータベースを整理した方法です。

Articles:

ID  Name
1   Paper clip
2   Water hose
3   Rubber duck

Features
ID    Articles_ID  Name    Value
1     1            Color   White
2     2            Color   Yellow
3     2            Length  1.4m
4     3            Color   Yellow

黄色の記事を見つけたい場合は、次のようにします。

SELECT distinct a.Name from Articles a join Features f
             where a.ID = f.Articles_ID
               and f.Name = "Color"
               and f.Value = "Yellow";

しかし、色が黄色で、長さの機能がない記事を検索したい場合はどうすればよいでしょうか。つまり、長さがないのでラバーダックが欲しいのですが、ウォーターホースは欲しくありません。

私のUIでは、次を選択できます。

Color: [ ] <empty>
       [x] Yellow
       [ ] White
       [ ] ...

Length: [x] <empty>
        [ ] 0.7m
        [ ] 1.4m
        [ ] ...

私の記事テーブルには最大 20,000 行あり、機能は最大 200,000 です。

おそらく、私のデータベースはこの種のクエリには適していませんか? 必要に応じて簡単に再生成できます。

4

1 に答える 1

1

(注:おそらく記事IDが必要ですが、その場合は必要ありません。DISTINCT結合の構文は次のようになりますtableA JOIN tableB ON condition。)

3つの可能性があります。すべての黄色の記事を取得してから、長さのあるすべての記事を除外することができます。

SELECT a.ID,
       a.Name
FROM Articles a
JOIN Features f ON a.ID = f.Articles_ID
WHERE f.Name = 'Color'
  AND f.Value = 'Yellow'
EXCEPT
SELECT a.ID,
       a.Name
FROM Articles a
JOIN Features f ON a.ID = f.Articles_ID
WHERE f.Name = 'Length'

または、サブクエリを使用して、対応するLengthレコードが存在しないレコードを照合します。

SELECT a.ID,
       a.Name
FROM Articles a
JOIN Features f ON a.ID = f.Articles_ID
WHERE f.Name = 'Color'
  AND f.Value = 'Yellow'
  AND NOT EXISTS (SELECT ID
                  FROM Features f2
                  WHERE f2.Articles_ID = a.ID
                    AND f2.Name = 'Length')

または、を使用しLEFT JOINてすべてのLength機能と結合し、そのような結合が成功しなかったレコードを照合します。(Color最初の機能結合の条件では、このクエリが最も定期的です。)

SELECT a.ID,
       a.Name
FROM Articles a
JOIN      Features f1 ON  a.ID = f1.Articles_ID
                      AND f1.Name = 'Color'
LEFT JOIN Features f2 ON  a.ID = f2.Articles_ID
                      AND f2.Name = 'Length'
WHERE f1.Value = 'Yellow'
  AND f2.Value IS NULL

どのクエリが最も効率的かは、使用しているインデックスと、SQLiteがそれらを使用することを決定したかどうかによって異なります。EXPLAINQUERYPLANを使用して確認します。

于 2012-11-30T10:37:43.710 に答える