Frage

Was ist ein vernünftiger Weg wäre DISTINCT und / oder GROUPBY ContentResolver- basierten Abfragen hinzuzufügen. Gerade jetzt muss ich benutzerdefinierte URI für jeden Sonderfall erstellen. Gibt es einen besseren Weg? (I noch Programm für 1,5 als kleinster gemeinsamer Nenner)

War es hilfreich?

Lösung 2

Da niemand zu beantworten, kam ich werde einfach sagen, wie ich dieses Problem gelöst. Grundsätzlich würde ich benutzerdefinierte URI für jeden Fall erstellen und die Kriterien in selection Parametern. Dann innerhalb ContentProvider#query würde ich den Fall identifizieren und rohe Abfrage erstellen, basierend auf Tabellennamen und Auswahlparametern.

Hier ist schnelles Beispiel:

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);

Andere Tipps

Sie können schön Hack tun, wenn contentResolver Abfrage verwenden:

String selection = Models.SOMETHING + "=" + something + ") GROUP BY (" + Models.TYPE;

Wenn Sie mit SELECT mehr DISTINCT verwenden möchten dann eine Spalte, müssen Sie GROUP BY verwenden.
Mini Hack über ContentResolver.query für diese:

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());
        }

Dieser Code wählen Sie eine letzte SMS für jeden der Sender vom Gerät Posteingang.
Hinweis: vor GROUP BY wir immer schreiben müssen mindestens eine Bedingung. Ergebnis SQL-Abfrage-String innerhalb ContentResolver.query Methode werden:

SELECT DISTINCT address, body FROM sms WHERE (type=1) AND (address IS NOT NULL) GROUP BY (address) 

Ihre überschriebene ContentProvider Abfragemethode eine bestimmte URI-Mapping müssen mit deutlich.

Dann SQLiteQueryBuilder verwenden und die setDistinct(boolean) Methode aufrufen.

@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;
}

Obwohl ich nicht verwendet haben Gruppen von , die ich verwendet habe Distinct in Inhalt Resolver-Abfrage.

Cursor cursor = contentResolver .query(YOUR_URI, new String[] {"Distinct "+ YOUR_COLUMN_NAME}, null, null, null);

In einer Bedingung können wir "distinct (COLUMN_NAME)" als Auswahl verwenden, und es funktioniert perfekt. aber in einem gewissen Zustand, es wird eine Ausnahme verursachen.

, wenn es eine Ausnahme verursachen, werde ich eine HashSet verwenden die Spaltenwerte zu speichern ....

// 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));

das Schlüsselwort distinct in der Projektion Hinzufügen auch für mich gearbeitet, aber es hat funktioniert nur, wenn das Schlüsselwort distinct das erste Argument war:

String[] projection = new String[]{"DISTINCT " + DBConstants.COLUMN_UUID, ... };

Vielleicht ist es einfacher verschiedene Werte zu erhalten, versuchen, das DISTINCT Wort vor dem Spaltennamen Sie wollen in den Projektionstisch

hinzufügen
String[] projection = new String[]{
                BaseColumns._ID,
                "DISTINCT "+ Mediastore.anything.you.want
};

und verwenden Sie es als Argument an Abfragemethode des Inhalts Resolver!

Ich hoffe, Ihnen zu helfen, denn ich habe die gleiche Frage vor einigen Tagen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top