¿Cómo unir dos tablas SQLite en mi aplicación Android?

Fondo

Tengo un proyecto de Android que tiene una base de datos con dos tablas: tbl_question y tbl_alternative .

Para poblar las vistas con preguntas y alternativas, estoy usando cursores. No hay problemas para obtener los datos que necesito hasta que bash unirme a las dos tablas.

     Tbl_question  
     -------------
     _carné de identidad  
     pregunta  
     categoria ID  
     Tbl_alternative
     ---------------
     _carné de identidad 
     questionid 
     categoria ID 
     alternativa

Quiero algo como lo siguiente:

 SELECT tbl_question.question, tbl_alternative.alternative where categoryid=tbl_alternative.categoryid AND tbl_question._id = tbl_alternative.questionid.` 

Este es mi bash:

 public Cursor getAlternative(long categoryid) { String[] columns = new String[] { KEY_Q_ID, KEY_IMAGE, KEY_QUESTION, KEY_ALT, KEY_QID}; String whereClause = KEY_CATEGORYID + "=" + categoryid +" AND "+ KEY_Q_ID +"="+ KEY_QID; Cursor cursor = mDb.query(true, DBTABLE_QUESTION + " INNER JOIN "+ DBTABLE_ALTERNATIVE, columns, whereClause, null, null, null, null, null); if (cursor != null) { cursor.moveToFirst(); } return cursor; 

Encuentro que esta forma de realizar consultas es más difícil que con el SQL normal, pero he recibido el consejo de usarlo de esta manera, ya que es menos propenso a errores.

Pregunta

¿Cómo puedo unir dos tablas SQLite en mi aplicación?

Necesitas el método rawQuery .

Ejemplo:

 private final String MY_QUERY = "SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.other_id WHERE b.property_id=?"; db.rawQuery(MY_QUERY, new String[]{String.valueOf(propertyId)}); 

Utilizar ? enlaces en lugar de poner valores en la consulta SQL sin formato.

Una forma alternativa es construir una vista que luego se consulta como una tabla. En muchos administradores de bases de datos que utilizan una vista pueden obtener un mejor rendimiento.

 CREATE VIEW xyz SELECT q.question, a.alternative FROM tbl_question AS q, tbl_alternative AS a WHERE q.categoryid = a.categoryid AND q._id = a.questionid; 

Esto es de memoria así que puede haber algunos problemas sintácticos. http://www.sqlite.org/lang_createview.html

Menciono este enfoque porque entonces puedes usar SQLiteQueryBuilder con la vista ya que implicabas que era preferible.

Además de la respuesta de @pawelzieba, que definitivamente es correcta, para unir dos tablas, mientras que puedes usar una INNER JOIN como esta

 SELECT * FROM expense INNER JOIN refuel ON exp_id = expense_id WHERE refuel_id = 1 

a través de una consulta sin formato como esta –

 String rawQuery = "SELECT * FROM " + RefuelTable.TABLE_NAME + " INNER JOIN " + ExpenseTable.TABLE_NAME + " ON " + RefuelTable.EXP_ID + " = " + ExpenseTable.ID + " WHERE " + RefuelTable.ID + " = " + id; Cursor c = db.rawQuery( rawQuery, null ); 

debido al soporte retrocompatible de SQLite de la forma primitiva de consulta, convertimos ese comando en esto:

 SELECT * FROM expense, refuel WHERE exp_id = expense_id AND refuel_id = 1 

y así poder aprovechar el método de ayuda SQLiteDatabase.query ()

 Cursor c = db.query( RefuelTable.TABLE_NAME + " , " + ExpenseTable.TABLE_NAME, Utils.concat(RefuelTable.PROJECTION, ExpenseTable.PROJECTION), RefuelTable.EXP_ID + " = " + ExpenseTable.ID + " AND " + RefuelTable.ID + " = " + id, null, null, null, null ); 

Para ver una publicación de blog detallada, consulte este http://blog.championswimmer.in/2015/12/doing-a-table-join-in-android-without-using-rawquery

“Columna ambigua” generalmente significa que el mismo nombre de columna aparece en al menos dos tablas; el motor de la base de datos no puede decir cuál quiere. Use nombres completos de tabla o alias de tabla para eliminar la ambigüedad.

Aquí hay un ejemplo que tuve en mi editor. Es por el problema de otra persona, pero debe tener sentido de todos modos.

 select P.* from product_has_image P inner join highest_priority_images H on (H.id_product = P.id_product and H.priority = p.priority)