我可以使用ContentResolver.query()执行此Android查询吗?(LEFT JOIN和CASE)

eid*_*lon 21 sql android left-join android-contentresolver android-contacts

我想在Android上执行以下查询(在伪代码中):

SELECT C.ID, C.NAME, CASE ISNULL(G.GROUPID,0) = 0 THEN 0 ELSE 1 END INGROUP
FROM CONTACTS C 
LEFT JOIN GROUPMEMBERSHIP G ON G.CONTACTID = C.ID AND G.GROUPID = ?
Run Code Online (Sandbox Code Playgroud)

我希望通过默认的Contacts ContentProvider选择系统通讯录中所有联系人的ID和名称,以及指示联系人是否是组成员的0/1字段?.

我当然可以很容易地获得所有联系人,然后在我的Adapter类中循环遍历并分别查询成员资格,但我想要执行两个查询,因为一个外部联接查询会产生更好的性能.

我可以使用标准的高级字符串投影和ContentResolver.query()方法吗?或者这种查询是否需要深入研究更直接的SQL执行?

jcw*_*ger 42

编辑: 好的,所以这实际上并没有解决问题,因为eidylon与他们的问题中提到的现有ContentProvider绑定.但是,如果您拥有ContentProvider源和API,这确实涵盖了如何进行JOIN.所以我会留给想要知道如何处理这种情况的人.


这很简单!但不直观...... :)

query(Uri uri, String[] projection, String selection, 
String[] selectionArgs, String sortOrder)
Run Code Online (Sandbox Code Playgroud)

好的,那么URI是什么?通常,每个表有一个URI.

content://com.example.coolapp.contacts从您的CONTACTS表中提供数据. content://com.example.coolapp.groupmembers从您的GROUPMEMBERSHIP表中提供数据.

但URI实际上只是一个字符串.随便使用它.在ContentProvider中创建一个响应代码块content://com.example.coolapp.contacts_in_group.在ContentProvider中的该代码块中,您可以获得对SQLite DB的原始访问权限,不受有限query()数据模型的限制.随意使用它!

根据需要定义您的选择字段.他们不具有映射到表的列名-映射他们你的需要,为了得到你的参数.

根据需要定义投影 - 连接后可能包含两个表中的列.

必,你已经完成了.谷歌在内部做这同样的模式在自己的代码-去看看联系人提供API -你看"bla.RawContact"和"bla.Contact"和作为等等内容的URI.每个数据库都在DB中的同一个表中提供数据 - 不同的URI只提供同一个表的不同视图!


Mac*_*rse 8

不,你不能用这种ContentResolver.query()方法做那种查询.你需要写这样的东西:

SQLiteDatabase db = YourActivity.getDbHelper().getReadableDatabase();
String query = yourLongQuery;
Cursor c = db.rawQuery(query, null);
YourActivity.startManagingCursor(c);
c.setNotificationUri(YourActivity.getContentResolver(), YourContentProvider.CONTENT_URI);
Run Code Online (Sandbox Code Playgroud)