我用很少的子查询和联合进行大查询:
public Cursor getCursor(int outlayType, long carId){
String selection;
String[] selectionArgs;
if(outlayType>0){
selection = "car_id=? and type=?";
selectionArgs = new String[]{
Long.toString(carId),Integer.toString(outlayType),
Long.toString(carId),Integer.toString(outlayType),
Long.toString(carId),Integer.toString(outlayType)};
}else{
selection = "car_id=?";
selectionArgs = new String[]{Long.toString(carId), Long.toString(carId), Long.toString(carId)};
}
String sql = "select (select count(*)+1 from outlays b where a.date < b.date and "+selection+") as countNum," +
" id as _id, id, type, note, sum, date," +
" odometer, unread, future, input_type, 0 as row_type " +
" from outlays a where "+ selection +" " +
" union " +
" select 0, 0, 0, 0, '', sum(sum), max(date)+2," +
" 0, 0, 0, '', 1 as row_type" +
" from outlays where "+ selection +" group by strftime('%Y-%m', date/1000, 'unixepoch')" +
" order by 7 DESC";
return sqdb.rawQuery(sql, selectionArgs);
}
它工作完美,但......
你可以看到:有几次我使用相同的 WHERE 条件。而这还不是结束。查询将增长。而且这个条件会被反复使用。
我想像这样使用临时表:
public Cursor getCursor(int outlayType, long carId){
String selection;
String[] selectionArgs;
if(outlayType>0){
selection = "car_id=? and type=?";
selectionArgs = new String[]{Long.toString(carId),Integer.toString(outlayType)};
}else{
selection = "car_id=?";
selectionArgs = new String[]{Long.toString(carId)};
}
sqdb.execSQL("drop table if exists sub");
sqdb.execSQL("create temp table sub " +
"as select * from outlays where "+selection, selectionArgs);
String sql = "select (select count(*)+1 from sub b where a.date < b.date) as countNum," +
" id as _id, id, type, note, sum, date," +
" odometer, unread, future, input_type, 0 as row_type " +
" from sub a " +
" union " +
" select 0, 0, 0, 0, '', sum(sum), max(date)+2," +
" 0, 0, 0, '', 1 as row_type" +
" from sub group by strftime('%Y-%m', date/1000, 'unixepoch')" +
" " +
" order by 7 DESC";
return sqdb.rawQuery(sql, null);
}
它看起来更好(对我来说),但是当我调用 Cursor.notifyDataSetChanged - 它工作错误。因为没有调用临时表的重新创建。
如何在游标的同一查询中执行一个子查询或一个临时表?