关于sql:我可以使用ContentResolver.query()执行此Android查询吗? (左加入和例)

Can I perform this Android query with ContentResolver.query()? (LEFT JOIN and CASE)

我正在寻找在Android上执行以下查询(以伪代码方式):

1
2
3
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执行?


编辑:好的,所以这实际上并不能解决所提出的问题,因为eidylon与其问题中提到的现有ContentProvider绑定在一起。但是,这确实涵盖了您拥有ContentProvider源代码和API时如何进行JOIN。因此,我会将其留给那些想知道如何处理这种情况的人。

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

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

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

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

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

根据需要定义选择字段。它们不必映射到表的列名,而是将它们映射为所需的形式,以获取参数。

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

Bing,您完成了。 Google在自己的代码中内部使用相同的模型-查看通讯录提供程序API-您会看到" bla.RawContact "和" bla.Contact "等作为内容URI。每个数据库都从DB的同一表中提供数据-不同的URI仅提供同一表的不同视图!


不,您不能使用ContentResolver.query()方法执行这种查询。
您将需要编写如下内容:

1
2
3
4
5
SQLiteDatabase db = YourActivity.getDbHelper().getReadableDatabase();
String query = yourLongQuery;
Cursor c = db.rawQuery(query, NULL);
YourActivity.startManagingCursor(c);
c.setNotificationUri(YourActivity.getContentResolver(), YourContentProvider.CONTENT_URI);


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

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

表或FROM子句没有参数。