Что было бы разумным способом добавить запросы DISTINCT
и/или GROUPBY
в ContentResolver
. Сейчас я должен создать пользовательский URI для каждого специального случая. Есть ли способ лучше?
(Я все еще программирую на 1,5 как самый низкий общий знаменатель)
Android: отличительный и GroupBy в ContentResolver
Ответ 1
Поскольку никто не пришел ответить, я просто расскажу, как я это решил. В принципе, я бы создал пользовательский 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
Вы можете сделать хороший взлом при запросе contentResolver, используйте:
String selection = Models.SOMETHING + "=" + something + ") GROUP BY (" + Models.TYPE;
Ответ 3
В вашем переопределенном методе запроса ContentProvider
есть определенное сопоставление URI для использования отдельных.
Затем используйте 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;
}
Ответ 4
Если вы хотите использовать 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());
}
Этот код выбирает один последний sms для каждого отправителя из входящих сообщений устройства.
Примечание: перед GROUP BY нам всегда нужно написать хотя бы одно условие.
Результат Строка запроса SQL внутри метода ContentResolver.query будет:
SELECT DISTINCT address, body FROM sms WHERE (type=1) AND (address IS NOT NULL) GROUP BY (address)
Ответ 5
Хотя я не использовал Group By, я использовал Distinct в запросе разрешения контента.
Cursor cursor = contentResolver
.query(YOUR_URI,
new String[] {"Distinct "+ YOUR_COLUMN_NAME},
null,
null, null);
Ответ 6
В некоторых условиях мы можем использовать "distinct (COLUMN_NAME)" как выбор, и он работает идеально. но в некоторых условиях это приведет к исключению.
когда он вызывает исключение, я буду использовать HashSet для хранения значений столбцов....
Ответ 7
// 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));
Ответ 8
Добавление ключевого слова Distinct в проецирование работало и для меня, однако, оно работало только тогда, когда ключевым словом был первый аргумент:
String[] projection = new String[]{"DISTINCT " + DBConstants.COLUMN_UUID, ... };
Ответ 9
Может быть, его проще получить отдельные значения, попробуйте добавить слово DISTINCT перед именем столбца, которое вы хотите в таблицу прогнозов
String[] projection = new String[]{
BaseColumns._ID,
"DISTINCT "+ Mediastore.anything.you.want
};
и использовать его в качестве аргумента для метода запроса для распознавателя контента!
Я надеюсь помочь вам, потому что у меня есть тот же вопрос до нескольких дней.