将DISTINCT
和/或GROUPBY
添加到基于ContentResolver
的查询是一种明智的方法。现在我必须为每个特殊情况创建自定义URI。有没有更好的办法?
(我仍然以1.5为最低共同标准编程)
答案 0 :(得分:40)
查询contentResolver时可以做得很好,使用:
String selection = Models.SOMETHING + "=" + something + ") GROUP BY (" + Models.TYPE;
答案 1 :(得分:15)
由于没有人来回答我只是想告诉我如何解决这个问题。基本上我会为每个案例创建自定义URI并传递selection
参数中的条件。然后在ContentProvider#query
内部,我将识别案例并根据表名和选择参数构建原始查询。
这是一个简单的例子:
switch (URI_MATCHER.match(uri)) {
case TYPES:
table = TYPES_TABLE;
break;
case TYPES_DISTINCT:
return db.rawQuery("SELECT DISTINCT type FROM types", null);
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
return db.query(table, null, selection, selectionArgs, null, null, null);
答案 2 :(得分:13)
在重写的ContentProvider
查询方法中,有一个特定的URI映射到使用distinct。
然后使用SQLiteQueryBuilder
并调用setDistinct(boolean)
方法。
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
boolean useDistinct = false;
switch (sUriMatcher.match(uri))
{
case YOUR_URI_DISTINCT:
useDistinct = true;
case YOUR_URI:
qb.setTables(YOUR_TABLE_NAME);
qb.setProjectionMap(sYourProjectionMap);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
// If no sort order is specified use the default
String orderBy;
if (TextUtils.isEmpty(sortOrder))
{
orderBy = DEFAULT_SORT_ORDER;
}
else
{
orderBy = sortOrder;
}
// Get the database and run the query
SQLiteDatabase db = mDBHelper.getReadableDatabase();
// THIS IS THE IMPORTANT PART!
qb.setDistinct(useDistinct);
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
if (c != null)
{
// Tell the cursor what uri to watch, so it knows when its source data changes
c.setNotificationUri(getContext().getContentResolver(), uri);
}
return c;
}
答案 3 :(得分:13)
如果要将DISTINCT与SELECT一起使用多一列,则需要使用GROUP BY。
使用以下内容的Mini Hack over ContentResolver.query:
Uri uri = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(uri,
new String[]{"DISTINCT address","body"}, //DISTINCT
"address IS NOT NULL) GROUP BY (address", //GROUP BY
null, null);
if(c.moveToFirst()){
do{
Log.v("from", "\""+c.getString(c.getColumnIndex("address"))+"\"");
Log.v("text", "\""+c.getString(c.getColumnIndex("body"))+"\"");
} while(c.moveToNext());
}
此代码从设备收件箱中为每个发件人选择最后一个短信。
注意:在GROUP BY之前,我们总是需要编写至少一个条件。
结果ContentResolver.query方法中的SQL查询字符串将:
SELECT DISTINCT address, body FROM sms WHERE (type=1) AND (address IS NOT NULL) GROUP BY (address)
答案 4 :(得分:6)
虽然我没有使用分组依据,但我在内容解析器查询中使用了 Distinct 。
Cursor cursor = contentResolver
.query(YOUR_URI,
new String[] {"Distinct "+ YOUR_COLUMN_NAME},
null,
null, null);
答案 5 :(得分:0)
在某些情况下,我们可以使用“distinct(COLUMN_NAME)”作为选择, 它完美无缺。 但在某些情况下,它会导致异常。
当它导致异常时,我将使用HashSet来存储列值....
答案 6 :(得分:0)
// getting sender list from messages into spinner View
Spinner phoneListView = (Spinner) findViewById(R.id.phone_list);
Uri uri = Uri.parse("content://sms/inbox");
Cursor c = getContentResolver().query(uri, new String[]{"Distinct address"}, null, null, null);
List <String> list;
list= new ArrayList<String>();
list.clear();
int msgCount=c.getCount();
if(c.moveToFirst()) {
for(int ii=0; ii < msgCount; ii++) {
list.add(c.getString(c.getColumnIndexOrThrow("address")).toString());
c.moveToNext();
}
}
phoneListView.setAdapter(new ArrayAdapter<String>(BankActivity.this, android.R.layout.simple_dropdown_item_1line, list));
答案 7 :(得分:0)
在投影中添加Distinct关键字也适用于我,但是,只有当distinct关键字是第一个参数时它才有效:
"$ ionic plugin add cordova-plugin-googlemaps --variable API_KEY_FOR_ANDROID="YOUR_ANDROID_API_KEY_IS_HERE" --variable API_KEY_FOR_IOS="YOUR_IOS_API_KEY_IS_HERE"
答案 8 :(得分:0)
当投影中有多个列时,您应该这样做:
DataTemplate
groupBySelection的右方括号和数字“ 1”是一个小技巧,但效果很好
答案 9 :(得分:0)
我创建了一个使用 group by 和 distinct 的实用方法。
以下是从 MMS 数据库中选择未见 thread_id
和最后一条消息日期的示例。
query(contentResolver= contentResolver,
select = arrayOf(Mms.THREAD_ID, "max(${Mms.DATE}) as date"),
from = Mms.CONTENT_URI,
where = "${Mms.SEEN} = 0",
groupBy = "1",
orderBy = "2 desc"
).use {
while (it?.moveToNext() == true){
val threadId = it.getInt(0)
val date = it.getLong(1)
}
}
fun query(
contentResolver: ContentResolver,
from: Uri,
select: Array<String>,
where: String? = null,
groupBy: Array<out String>? = null,
distinct: Boolean = false,
selectionArgs: Array<out String>? = null,
orderBy: String? = null,
): Cursor? {
val tmpSelect = select[0]
val localWhere =
if (groupBy == null) where
else "${where ?: "1"}) group by (${groupBy.joinToString()}"
if (distinct) {
select[0] = "distinct $tmpSelect"
}
val query = contentResolver.query(from, select, localWhere, selectionArgs, orderBy)
select[0] = tmpSelect
return query
}
答案 10 :(得分:-1)
也许更简单的获得不同的价值观, 尝试在您想要的列名称之前将DISTINCT字添加到投影表
中String[] projection = new String[]{
BaseColumns._ID,
"DISTINCT "+ Mediastore.anything.you.want
};
并将其用作查询内容解析器方法的参数!
我希望能帮助你,因为我在某些日子之前有同样的问题