我是数据库新手,所以可能很容易。 我有以下数据库结构: 表产品
表格过滤器(可能包含类似内容)
表关系(仅包含产品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)。如何编写选择以动态添加任何过滤器组合?如何在上面的例子中重写查询?
谢谢
答案 0 :(得分:1)
您可以使用Dynamic Query实现此目的。 我对PostgreSql了解不多,但我知道SQL Server,所以我举一个例子来做同样的事情。
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)
答案 1 :(得分: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)
)
这样我就可以拥有任意数量的过滤器。