J'ai un projet Android qui possède une base de données avec deux tables: tbl_question
et tbl_alternative
.
Pour remplir les vues avec des questions et des alternatives, j'utilise des curseurs. Il n’ya aucun problème à obtenir les données dont j’ai besoin jusqu’à ce que je tente de joindre les deux tables.
Tbl_question ------------- _Id Question Categoryid
Tbl_alternative --------------- _Id Questionid Categoryid Alternative
Je veux quelque chose comme ce qui suit:
SELECT tbl_question.question, tbl_alternative.alternative where
categoryid=tbl_alternative.categoryid AND tbl_question._id =
tbl_alternative.questionid.`
Ceci est ma tentative:
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;
Je trouve cette façon de former des requêtes plus ardue que le SQL ordinaire, mais j'ai eu le conseil de l'utiliser de cette façon car il est moins sujet aux erreurs.
Comment joindre deux tables SQLite dans mon application?
Vous avez besoin de la méthode rawQuery .
Exemple:
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)});
Utilisation ? des liaisons au lieu de mettre des valeurs dans une requête sql brute.
Une autre méthode consiste à créer une vue qui est ensuite interrogée comme une table. Dans de nombreux gestionnaires de bases de données, l’utilisation d’une vue peut améliorer les performances.
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;
C’est de mémoire, il peut donc y avoir des problèmes de syntaxe. http://www.sqlite.org/lang_createview.html
Je mentionne cette approche car vous pouvez alors utiliser SQLiteQueryBuilder avec la vue car vous avez laissé entendre que cela était préférable.
En plus de la réponse de @ pawelzieba, qui est sans aucun doute correcte, de joindre deux tables, alors que vous pouvez utiliser un INNER JOIN
comme ça
SELECT * FROM expense INNER JOIN refuel
ON exp_id = expense_id
WHERE refuel_id = 1
via une requête brute comme celle-ci -
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
);
en raison de la compatibilité ascendante de SQLite avec la méthode primitive d'interrogation, nous transformons cette commande en ceci -
SELECT *
FROM expense, refuel
WHERE exp_id = expense_id AND refuel_id = 1
et donc être en mesure de tirer parti de la méthode d'assistance 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
);
Pour un article de blog détaillé, vérifiez ceci http://blog.championswimmer.in/2015/12/doing-a-table-join-in-Android-without-using-rawquery
"Colonne ambiguë" signifie généralement que le même nom de colonne apparaît dans au moins deux tableaux; le moteur de base de données ne peut pas dire lequel vous voulez. Utilisez des noms de table complets ou des alias de table pour supprimer toute ambiguïté.
Voici un exemple que j'ai eu dans mon éditeur. Cela vient du problème de quelqu'un d'autre, mais devrait quand même avoir un sens.
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)