1

私はデータベースが初めてなので、とても簡単かもしれません。次のデータベース構造があります: テーブル製品

テーブル フィルター(次のようなものを含めることができます)

  • 青色
  • カラー ブラック
  • 赤色
  • サイズ小
  • ブランド X

テーブル関係(製品 ID とフィルター ID のみを持つ)

黒または赤の小さい製品をすべて取得したいとします。次のクエリを書きました。

SELECT products.name FROM products 
JOIN pfrelation ON
    ((pfrelation.filter_id=18) AND (pfrelation.filter_id=11 OR pfrelation.filter_id=13) AND products.id=pfrelation.product_id) 

上記の例では、11 と 13 は黒と赤を表し、18 は小の ID です。ご想像のとおり、上記のクエリには結果がありません (ID を 18 と 11/13 の両方にすることはできません)。フィルタの任意の組み合わせを動的に追加するために選択を記述するにはどうすればよいですか? 上記の例のクエリを書き直すにはどうすればよいですか?

ありがとうございました

4

2 に答える 2

1

これは動的クエリで実現できます。PostgreSql についてはあまり知りませんが、SQL Server は知っているので、同じことを行う例を示しています。

SQLFiddel デモはこちら

Create table Product(pid int,name varchar(10),color varchar(10),brand varchar(10),size varchar(10));
insert into product values(1,'ABC','red','X','small');
create table pfrelation(pid int,fid int,relation varchar(100));
insert into pfrelation values(1,10,'Color=''blue''');
insert into pfrelation values(1,11,'Color=''black''');
insert into pfrelation values(1,13,'Color=''red''');
insert into pfrelation values(1,18,'size=''small''');
insert into pfrelation values(1,20,'brand=''X''');

Declare @sql varchar(200)

select @sql = ((select 'pr.' + relation from pfrelation where fid = 18) 
   + ' and (' + 
(select 'pr.' + relation from pfrelation where fid = 11) 
   + ' or '   + 
(select 'pr.' + relation from pfrelation where fid = 13) 
   + ') and pr.pid=pf.pid' ) 
select @sql
print('select * from Product pr,pfrelation pf where '+@sql)
exec('select * from Product pr,pfrelation pf where '+@sql)
于 2013-06-26T11:42:01.890 に答える
1

この方法でクエリを動的に作成します。

public ArrayList<Products> getFilteredOnlinePictures( Hashtable<String, List<String>> filters,..)
{
    SQLiteDatabase db = getWritableDatabase();
    // create query conditions
    StringBuffer filtersQuery = new StringBuffer();
    for (String key: Collections.list(filters.keys()))
    {
        List<String> filtersValues = filters.get(key);
        if (filtersQuery.length() > 0)
            filtersQuery.append(" INTERSECT ");
        filtersQuery.append("SELECT " + TABLE_PFRELATIONS + "." + COLUMN_PRODUCT_ID
            + " FROM " + TABLE_PFRELATIONS + " WHERE " + TABLE_PFRELATIONS + "."
            + COLUMN_FILTER_ID + " IN (");
        for (String value: filtersValues)
        {
            long filterID = getIDForFilter(db, key, value);
            filtersQuery.append(filterID);
            if (filtersValues.indexOf(value) == (filtersValues.size() - 1))
            {
                // this is the last value
                filtersQuery.append(")");
            }
            else
            {
                // there are more values
                filtersQuery.append(",");
            }

        }
    }
    if (filtersQuery.length() > 0)
    {
        filtersQuery.append(")");
        filtersQuery.insert(0, " WHERE " + TABLE_PRODUCTS + ".id" + " IN (");
    }
    String sql = "SELECT " + TABLE_PRODUCTS + "." + COLUMN_NAME + " FROM " + TABLE_PRODUCTS + filtersQuery.toString();
    Cursor c = db.rawQuery(sql, null); ...

例として与えられたクエリは次のようになります。

SELECT products.name FROM products
WHERE products.id IN (
    SELECT pfrelation.product_id FROM pfrelation WHERE pfrelation.filter_id IN (18) 
    INTERSECT 
    SELECT pfrelation.product_id FROM pfrelation WHERE pfrelation.filter_id IN (11,13)
    ) 

このようにして、任意の数の値を持つ任意のフィルターを作成できます。

于 2013-06-26T11:55:36.703 に答える