我正在开发一个短信应用程序,我试图从每次对话中获取最新的短信。
这是我的SQL语句:
SELECT MAX(smsTIMESTAMP) AS smsTIMESTAMP,_id, smsID, smsCONID, smsMSG, smsNUM, smsREAD, smsTYPE, smsSHORTMSG, COUNT(*) AS smsNUMMESSAGES FROM sms GROUP BY smsCONID ORDER BY smsTIMESTAMP desc
我在SQLite Expert中运行了查询,并且得到了正确的响应:
但是,当我在应用程序中运行它时,我得到:
这是我的桌子
这是我的Datamanipulator类:
public class DataManipulator { private static final String DATABASE_NAME = "smsapplication.db"; private static final int DATABASE_VERSION = 3; static final String TABLE_NAME = "sms"; private static Context context; static SQLiteDatabase db; private static DataManipulator instance; private SQLiteStatement insertStmt; private static final String INSERT = "insert or ignore into " + TABLE_NAME + " (smsID, smsCONID, smsMSG, smsNUM, smsREAD, smsTIMESTAMP, smsTYPE, smsSHORTMSG) values (?,?,?,?,?,?,?,?)"; public DataManipulator(Context context) { DataManipulator.context = context; OpenHelper openHelper = new OpenHelper(DataManipulator.context); DataManipulator.db = openHelper.getWritableDatabase(); this.insertStmt = DataManipulator.db.compileStatement(INSERT); } public static DataManipulator getInstance(Context mContext) { if(instance == null) { instance = new DataManipulator(mContext); } return instance; } public long insert(int smsID, int smsCONID, String smsMSG, String smsNUM, int smsREAD, long smsTIMESTAMP, String smsTYPE, String smsSHORTMSG) { this.insertStmt.bindLong(1, smsID); this.insertStmt.bindLong(2, smsCONID); this.insertStmt.bindString(3, smsMSG); this.insertStmt.bindString(4, smsNUM); this.insertStmt.bindLong(5, smsREAD); this.insertStmt.bindString(6, String.valueOf(smsTIMESTAMP)); this.insertStmt.bindString(7, smsTYPE); this.insertStmt.bindString(8, smsSHORTMSG); return this.insertStmt.executeInsert(); } public void deleteAll() { db.delete(TABLE_NAME, null, null); } public Cursor getLastSmsForAllConversations() { Cursor cursor = db.query(TABLE_NAME, new String[] {"_id"," MAX(smsTIMESTAMP) AS smsTIMESTAMP ", "smsCONID", "smsNUM", "smsREAD", "smsTYPE","smsSHORTMSG","COUNT(*) AS smsNUMMESSAGES" }, null, null, "smsCONID", null, "smsTIMESTAMP desc"); return cursor; } public Cursor getConversationMessages(int conID) { Cursor cursor = db.query(TABLE_NAME, new String[] {"_id", "smsID", "smsCONID", "smsMSG", "smsNUM", "smsREAD", "smsTIMESTAMP", "smsTYPE","smsSHORTMSG" }, "smsCONID="+conID, null, null, null, "smsTIMESTAMP asc"); return cursor; } public void printCursor() { Cursor cursor = db.rawQuery("SELECT MAX(smsTIMESTAMP) AS smsTIMESTAMP,_id, smsID, smsCONID, smsMSG, smsNUM, smsREAD, smsTYPE, smsSHORTMSG, COUNT(*) AS smsNUMMESSAGES FROM sms GROUP BY smsCONID ORDER BY smsTIMESTAMP desc", null); // db.query(TABLE_NAME, new String[] {"_id","smsTIMESTAMP AS smsTIMESTAMP ", "smsCONID", "smsNUM", "smsREAD", "smsTYPE","smsSHORTMSG" },"smsCONID=40", null, null, null, "smsTIMESTAMP desc"); if (cursor.moveToFirst()){ do{ String data =""; data= cursor.getString(cursor.getColumnIndex("smsTIMESTAMP"))+" - " +cursor.getString(cursor.getColumnIndex("smsSHORTMSG")); Log.i("data", data); }while(cursor.moveToNext()); } cursor.close(); } private static class OpenHelper extends SQLiteOpenHelper { OpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER , smsID INTEGER PRIMARY KEY, smsCONID INTEGER, smsMSG TEXT,smsNUM TEXT, smsREAD INTEGER, smsTIMESTAMP INTEGER, smsTYPE TEXT, smsSHORTMSG TEXT)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } @Override public synchronized void close() { if (db != null) db.close(); super.close(); } } }
使用时GROUP BY,结果的每一行对应于原始表的多行。这些结果的计算有三种可能性:
GROUP BY
MAX
COUNT
MIN
要解决您的问题,您必须首先使用aGROUP BY获取足够的信息以标识所需的记录:
SELECT smsCONID, -- OK: used in GROUP BY MAX(smsTIMESTAMP) AS smsTIMESTAMP, -- OK: aggregate MAX COUNT(*) AS smsNUMMESSAGES -- OK: aggregate COUNT FROM sms GROUP BY smsCONID ORDER BY smsTIMESTAMP DESC
然后,将该结果表与原始sms表连接起来以获取这些记录的其他列:
sms
SELECT * FROM (SELECT smsCONID, MAX(smsTIMESTAMP) AS smsTIMESTAMP, COUNT(*) AS smsNUMMESSAGES FROM sms GROUP BY smsCONID) AS grouped JOIN sms ON grouped.smsCONID = sms.smsCONID AND grouped.smsTIMESTAMP = sms.smsTIMESTAMP ORDER BY smsTIMESTAMP DESC