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

时间:2011-06-14 03:38:31

标签: android sql left-join android-contacts android-contentresolver

我希望在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 = ?

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

我当然可以轻松地获得所有联系人,然后在我的Adapter类中单独循环并查询成员资格,但我想要执行两个查询,因为一个外部联接查询会产生更好的性能。

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

3 个答案:

答案 0 :(得分:41)

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


这很容易!但不直观......:)

query(Uri uri, String[] projection, String selection, 
String[] selectionArgs, String sortOrder)

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

content://com.example.coolapp.contacts提供CONTACTS表格中的数据。 content://com.example.coolapp.groupmembersGROUPMEMBERSHIP表中提供数据。

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

根据需要定义您的选择字段。他们没有 映射到表列名称 - 为了获取参数,将它们映射到您需要的位置。

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

Bing,你已经完成了。 Google在自己的代码中内部使用相同的模型 - 查看Contacts provider API - 您将“bla.RawContact”和“bla.Contact”等视为内容URI。每个数据库都在数据库中的同一个表中提供数据 - 不同的URI只提供同一个表的不同视图

答案 1 :(得分:7)

不,您不能使用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);

答案 2 :(得分:0)

您不能这样做,因为ContentResolver只有一个查询方法:

    query(Uri uri, String[] projection, String selection, 
String[] selectionArgs, String sortOrder)

表或FROM子句没有参数。