我有两个表如下所示:
Table1
_id | _key | _mime_type | _hash
---------------------------
和
Table2
_id | _path | _mimetype
-------------------
我可以通过我的内容提供程序query()方法中的以下命令执行UNION查询来获取带有结果集的有效游标:
String unionQuery = " SELECT "
+ Table1._ID + " AS _id, "
+ Table1.QUICK_KEY + " AS _key, "
+ Table1.MIME_TYPE + " AS _mime,"
+ Table1.HASH + " AS _hash,"
+ "NULL as _path_to_file"
+ " FROM " + Table1
+ " UNION "
+ " SELECT "
+ Table2._ID + " AS _id, "
+ "NULL AS _key, "
+ Table2.MIME_TYPE + " AS _mime,"
+ "NULL AS _hash,"
+ Table2.PATH + " as _path_to_file"
+ " FROM " + Table2;
return db.rawQuery(unionQuery, null);
我不想手动编写上面的语句,而是使用SQLiteQueryBuilder类中的buildUnionSubQuery()方法。
buildUnionSubQuery()文档位于http://developer.android.com/reference/android/database/sqlite/SQLiteQueryBuilder.html
我一直在尝试使用该方法,但是在创建我手动编写的SQL语句时没有运气。
我尝试的代码的一个例子(我尝试了大约10种不同的东西)是: SQLiteQueryBuilder cloudQueryBuilder = new SQLiteQueryBuilder(); SQLiteQueryBuilder localQueryBuilder = new SQLiteQueryBuilder();
String typeDiscriminatorColumn = "_table";
Set<String> cloudColumns = new HashSet<String>();
cloudColumns.add(FileInfos.column(Table1._ID));
cloudColumns.add(FileInfos.column(Table1.QUICK_KEY));
cloudColumns.add(FileInfos.column(Table1.MIME_TYPE));
cloudColumns.add(FileInfos.column(Table1.HASH));
cloudQueryBuilder.setTables(Table1);
String cloudTableQuery = cloudQueryBuilder.buildUnionSubQuery(typeDiscriminatorColumn, projection, cloudColumns, 0, Table1, selection, null, null);
使用该代码,这是我在记录查询语句时得到的结果:
SELECT quickkey, NULL AS _id, NULL AS hash, NULL AS created, NULL AS mimetype, NULL AS _id, NULL AS _mimetype, NULL AS _path FROM Table1
我尝试过的一些其他示例最终会得到相同的结果,其中几乎所有的表列都是“NULL AS”
但我的目标是让查询语句(对于UNION查询中的每个SELECT语句)匹配我手动编写的union语句。
列顺序无关紧要。
感谢任何帮助。
修改
我知道buildUnionQueries()用于添加多个SELECT语句,但问题是SELECT语句没有像我期望的那样被创建(这意味着我正在使用buildUnionSubquery()方法,这是什么我正在寻求帮助)
修改
以下代码大部分都有效,除了排序似乎不起作用:
SQLiteQueryBuilder cloudQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder localQueryBuilder = new SQLiteQueryBuilder();
String typeDiscriminatorColumn = "type";
String[] cloudUnionColumns = {
FileInfos._ID,
FileInfos.QUICK_KEY,
FileInfos.MIME_TYPE,
FileInfos.CREATED,
FileInfos.HASH,
LocalItems.PATH,
};
Set<String> cloudColumns = new HashSet<String>();
cloudColumns.add(FileInfos._ID);
cloudColumns.add(FileInfos.QUICK_KEY);
cloudColumns.add(FileInfos.MIME_TYPE);
cloudColumns.add(FileInfos.HASH);
cloudColumns.add(FileInfos.CREATED);
cloudQueryBuilder.setTables(Tables.FILE_INFOS);
String cloudTableQuery = cloudQueryBuilder.buildUnionSubQuery(typeDiscriminatorColumn, cloudUnionColumns, cloudColumns, 0, "cloud", selection, null, null);
String[] localUnionColumns = {
LocalItems._ID,
FileInfos.QUICK_KEY,
LocalItems.MIME_TYPE,
LocalItems.CREATED,
FileInfos.HASH,
LocalItems.PATH,
};
Set<String> localColumns = new HashSet<String>();
localColumns.add(LocalItems._ID);
localColumns.add(LocalItems.PATH);
localColumns.add(LocalItems.MIME_TYPE);
localColumns.add(LocalItems.CREATED);
localQueryBuilder.setTables(Tables.LOCAL_ITEMS);
String localTableQuery = localQueryBuilder.buildUnionSubQuery(typeDiscriminatorColumn, localUnionColumns, localColumns, 0, "local", selection, null, null);
Log.i(TAG, "cloud sub query - " + cloudTableQuery);
Log.i(TAG, "local sub query - " + localTableQuery);
String[] subQueries = {
cloudTableQuery,
localTableQuery,
};
sortOrder = "created DESC";
String unionQuery = cloudQueryBuilder.buildUnionQuery(subQueries, sortOrder, null);
Log.i(TAG, "query - " + unionQuery);
return db.rawQuery(unionQuery, null);
我回来的示例行:
[_id: 33][quickkey: null][mimetype: image/jpeg][created: 1413327563000][hash: null][_path: /storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20141014-WA0001.jpg]
[_id: 47][quickkey: null][mimetype: image/jpeg][created: 1415751020000][hash: null][_path: /storage/emulated/0/Download/dota_2___clockwerk_by_sheron1030-d855txk.jpg]
我知道这些行是本地项目,因为quickkey = null且hash = null
[_id: 181][quickkey: 88hcvu3t3y832p4][mimetype: image/gif][created: 1414021932000][hash: 86a15752bb550259d89e184bb5930306a9f3c8b390837b6f9b387816b6dcd461][_path: null]
[_id: 257][quickkey: 57b35uy9f12a462][mimetype: image/png][created: 1410831493000][hash: 3ad838b6a5543760b588655ad9a1714c19ecb1b91a326a21282596b2fb650c48][_path: null]
我知道这些行是云项,因为path = null
虽然排序不起作用,并且列名没有别名(我也不知道如何),因为我希望对“已创建”列进行排序,但它们不会对整个结果集进行排序。而是分别为每个语句进行排序。
答案 0 :(得分:2)
该方法似乎不支持x AS y
。至少不是你需要的方式。
typeDiscriminator{Column|Value}
这些参数允许您在结果中包含一个列,以便您区分行所在的联合子查询:
SELECT
'one' AS sourceTable
...
FROM table1
UNION SELECT
'two' AS sourceTable
...
FROM table2
其中
typeDiscriminatorColumn
是"sourceTable"
,typeDiscriminatorValue
在第一个unionSubQuery中为"one"
,在第二个"two"
unionColumns
两者都是常量,必须包含"sourceTable"
unionColumns
vs columnsPresentInTable
unionColumns
或多或少是最终projection
。但是,列会被修改,最重要的是取决于columnsPresentInTable
。但它所做的只是保持不变,或者如果该列不存在则用"NULL AS " + unionColumnEntry
替换它。这允许您对具有完全相同列名的表执行联合查询:
SELECT
column1,
column2,
NULL AS column3
...
UNION SELECT
NULL AS column1,
column2,
column3,
...
具有以下内容:
unionColumns
为{ "column1", "column2", "column3" }
columnsPresentInTable
在第一个子查询中为{ "column1", "column2" }
,在第二个子查询中为{ "column2", "column3" }
。 NULL AS <whatever>
是因为您根本没有相同的列名。遗憾的是,通过AS
进行映射并非此方法的意图。
您可以做的是在手动处理NULL
和AS
部分时使用略微手动的#buildQuery方法
String[] projectionIn = {
Table1._ID + " AS _id",
...
"NULL as _path_to_file"
}
cloudQueryBuilder.buildQuery(projectionIn, null, null, ...);
或者你自己写了一个类似的方法来实际做你想要的。
参考文献: