SQLite: Cómo unir tablas y presentar el cursor usando SimpleCursorAdapter

He estado usando SQLite en Android por mucho tiempo, pero es mi primera vez para realizar una operación de tabla de unión. Estoy totalmente frustrado porque he estado trabajando en él todo el día.

Ahora tengo 2 tablas, FTSProfile y FTSCell, y quiero unirlas usando una llave común A con un LEFT JOIN. Así que implementé una serie de código, ContentProvider y Database para realizar lo que quiero. En la base de datos, he utilizado SQLiteQueryBuilder para construir la consulta y, por tanto, obtener el cursor que quiero. Solía:

SQLiteQueryBuilder builder = new SQLiteQueryBuilder(); builder.setTables(FTS_VIRTUAL_TABLE_PROFILE+" LEFT JOIN "+FTS_VIRTUAL_TABLE_CELL+" ON "+FTS_VIRTUAL_TABLE_CELL+"."+Database.KEY_CID+"="+FTS_VIRTUAL_TABLE_PROFILE+"."+Database.KEY_CELL_ID); builder.setProjectionMap(mColumnMap_CombinedTable); 

Y mi Hashmap es como:

 HashMap<String,String> map = new HashMap<String,String>(); for (String key: KEYS_PROFILE) map.put(key, FTS_VIRTUAL_TABLE_PROFILE+"."+key); for (String key: KEYS_CELL) map.put(key, FTS_VIRTUAL_TABLE_CELL+"."+key); map.put(BaseColumns._ID, BaseColumns._ID); map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID); map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "rowid AS " + SearchManager.SUGGEST_COLUMN_SHORTCUT_ID); 

Y entonces cuando corro el programa e intento abrir la lista para el resultado, consigo un SQLiteException: no such column: _id...

No tengo ideas de cómo resolverlo, pero realmente quiero saber cómo puedo deshacerme de él. ¿Alguien puede ayudar?

Ha pregunta divertida. Sólo estaba mirando lo mismo hace 30 minutos;). Usted podría intentar seguir el ejemplo como en utilizado en la aplicación de contacto nativo androide.

http://www.google.com/codesearch/p?hl=es#cbQwy62oRIQ/src/com/android/providers/contacts/ContactsProvider2.java&q=ContactsProvider.java&d=5

Declaran una interfaz

 private interface DataContactsQuery { public static final String TABLE = "data " + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " + "JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; public static final String[] PROJECTION = new String[] { RawContactsColumns.CONCRETE_ID, DataColumns.CONCRETE_ID, ContactsColumns.CONCRETE_ID }; public static final int RAW_CONTACT_ID = 0; public static final int DATA_ID = 1; public static final int CONTACT_ID = 2; } 

Entonces al intentar consultar los resultados utilizan este pedazo de código.

 Cursor cursor = null; try { cursor = mDb.query(DataContactsQuery.TABLE, DataContactsQuery.PROJECTION, mSb.toString(), mSelectionArgs.toArray(EMPTY_STRING_ARRAY), null, null, Contacts.IN_VISIBLE_GROUP + " DESC, " + Data.RAW_CONTACT_ID); if (cursor.moveToFirst()) { dataId = cursor.getLong(DataContactsQuery.DATA_ID); rawContactId = cursor.getLong(DataContactsQuery.RAW_CONTACT_ID); contactId = cursor.getLong(DataContactsQuery.CONTACT_ID); } else { // No contact found, return a null URI return -1; } } finally { if (cursor != null) { cursor.close(); } } 

¿Es útil?

¿Qué hay de crear una VIEW en su base de datos? Si se trata de una consulta frecuente, su superficie como una vista, y se puede evitar una gran cantidad de la confusión de la creación de la unión, y sólo preocuparse por los criterios de selección. Si puede escribir la combinación como SQL recto, entonces debería ser capaz de crear una vista en ella y luego usarla.

El problema que veo con tu código parece ser que estás intentando seleccionar una columna llamada _id (que se necesita para un CursorAdapter ), pero esa columna no existe. Estás asignando BaseColumns._ID a BaseColumns._ID , pero esas son sólo constantes, y si tu base de datos no tiene una columna _id , entonces obtendrás el error que estás viendo.

 CREATE VIEW FooBar AS SELECT Foo.field1 AS FooField1, Foo.field2 AS FooField2, Bar.field1 AS BarField1, Bar.field2 AS BarField2, (Foo._id * 1000000000) + Bar._id AS _id FROM Foo LEFT JOIN Bar ON Foo.Field1 = Bar.Field2; 

Esa (Foo._id * 1000000000) + Bar._id AS _id es una manera rápida, sucia y probablemente dolorosamente incorrecta de sintetizar un _id único para la fila devuelta por la vista, que necesitará si está utilizando esto como un adaptador. También tiene la desventaja de ser de sólo lectura. No se puede actualizar una vista.

Una vez que tenga su VIEW , puede SELECT contra ella como si fuera una tabla en sí. Es decir, SELECT * FROM FooBar WHERE BarField1 > 10;

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.