Aller au contenu

Utiliser une fonction d'agrégat via rawQuery sur 2 tables...


Recommended Posts

Bonsoir à tous,

J'essaye de réaliser cette requête, mais à priori, cela semble impossible :

return db.rawQuery("SELECT transactions._id, utilisateurs._id, SUM(transactions.montantTransaction) as total , utilisateurs.nomUtilisateur FROM transactions " +
			"JOIN utilisateurs ON utilisateurs._id=transactions.idUtilisateurTransaction " +
			"WHERE transactions.idUtilisateurTransaction=" + argument + " GROUP BY utilisateurs.nomUtilisateur, transactions._id, utilisateurs._id"
			, null);

En y allant à tatons, je me suis rendu compte que je pouvais aller jusqu'ici :

return db.rawQuery("SELECT transactions._id, utilisateurs._id,  utilisateurs.nomUtilisateur FROM transactions " +
			"JOIN utilisateurs ON utilisateurs._id=transactions.idUtilisateurTransaction " +
			"WHERE transactions.idFichierTransaction=" + argument + " GROUP BY utilisateurs.nomUtilisateur, transactions._id, utilisateurs._id"
			, null);

Mais que dès que je rajoutais ma fonction d'agrégat, ça ne fonctionnait plus !

En effet, dans ce cas, j'ai droit à cette erreur : 02-21 18:08:41.705: ERROR/AndroidRuntime(862): java.lang.IllegalArgumentException: column '_id' does not exist

Cependant, dans mon GROUP BY, je fais bien apparaître mes 2 champs _id de mes 2 tables...

Si, c'est effectivement impossible de le faire par ce moyen, comment puis je faire ?

Merki :)

Lien vers le commentaire
Partager sur d’autres sites

Est-ce que, par hasard, tu injectes le Cursor résultant de rawQuery dans un Adapter ? Parce que ce genre d'erreur est plutôt généré par un Cursor; ça ne serait pas forcément un problème de requête impossible, mais plutôt d'incompatibilité de la requête avec un Cursor...

Lien vers le commentaire
Partager sur d’autres sites

Est-ce que, par hasard, tu injectes le Cursor résultant de rawQuery dans un Adapter ? Parce que ce genre d'erreur est plutôt généré par un Cursor; ça ne serait pas forcément un problème de requête impossible, mais plutôt d'incompatibilité de la requête avec un Cursor...

Très bonne remarque !

Effectivement, tu vises dans le mille !

Voici ce que je fais avec lerésultat (qui vient de recuprererRecapParFichier()) :

		Cursor c = db.recupererRecapParFichier(argument);
	startManagingCursor(c);
	SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.listrecapfichier, c, new String[]{"utilisateurs.nomUtilisateur"}, new int[] {R.id.listTotal});
	this.getListView().setAdapter(adapter);

Cependant, comme ma requête est censée me retourner plusieurs lignes, que dois je utiliser à la place d'un cursor ?

Merci à toi en tout cas ! :)

Lien vers le commentaire
Partager sur d’autres sites

En fait le problème n'est pas, à la base, le Cursor, mais le CursorAdapter, qui a besoin d'une colonne nommée _id dans la réponse du Cursor, pour pouvoir fonctionner.

Dans ton cas, tu n'as pas de telle colonne dans ton résultat (tes colonnes étant nommées 'transactions._id', 'utilisateurs._id' et 'utilisateurs.nom') (Ceci-dit, c'est le cas dans les deux exemples de requêtes que tu donnes, y compris celle qui fonctionne, ce qui est en contradiction avec mon explication... )

Tu peux peut-être résoudre ton problème en donnant des alias à tes colonnes de résultat.

Ce qui donnerai

return db.rawQuery("SELECT transactions._id as _id, utilisateurs._id as userId, SUM(transactions.montantTransaction) as total , utilisateurs.nomUtilisateur FROM transactions " +
                               "JOIN utilisateurs ON utilisateurs._id=transactions.idUtilisateurTransaction " +
                               "WHERE transactions.idUtilisateurTransaction=" + argument + " GROUP BY utilisateurs.nomUtilisateur, transactions._id, utilisateurs._id"
                               , null);

Lien vers le commentaire
Partager sur d’autres sites

En fait le problème n'est pas, à la base, le Cursor, mais le CursorAdapter, qui a besoin d'une colonne nommée _id dans la réponse du Cursor, pour pouvoir fonctionner.

Dans ton cas, tu n'as pas de telle colonne dans ton résultat (tes colonnes étant nommées 'transactions._id', 'utilisateurs._id' et 'utilisateurs.nom') (Ceci-dit, c'est le cas dans les deux exemples de requêtes que tu donnes, y compris celle qui fonctionne, ce qui est en contradiction avec mon explication... )

Tu peux peut-être résoudre ton problème en donnant des alias à tes colonnes de résultat.

Ce qui donnerai

return db.rawQuery("SELECT transactions._id as _id, utilisateurs._id as userId, SUM(transactions.montantTransaction) as total , utilisateurs.nomUtilisateur FROM transactions " +
                               "JOIN utilisateurs ON utilisateurs._id=transactions.idUtilisateurTransaction " +
                               "WHERE transactions.idUtilisateurTransaction=" + argument + " GROUP BY utilisateurs.nomUtilisateur, transactions._id, utilisateurs._id"
                               , null);

Effectivement, le problème venait du fait que _id n'existait pas ...

(à force de triturer la requête dans tout les sens, on en perd l'essentiel !)

Ceci dit, ce qui est étrange, c'est qu'un champ _id est obligatoire, même si c'est juste l'alias du champ... Donc je comprend pas trop le pourquoi du comment...

M'enfin !

Pour ceux que ça pourrait titiller :

		return db.rawQuery("SELECT SUM(transactions.montantTransaction) as total , utilisateurs.nomUtilisateur as _id FROM transactions " +
			"JOIN utilisateurs ON utilisateurs._id=transactions.idUtilisateurTransaction " +
			"WHERE transactions.idFichierTransaction=" + argument + " GROUP BY utilisateurs.nomUtilisateur"
			, null);

Merci chpil, tu as été le plus rapide ;-) (http://stackoverflow.com/questions/5081096/android-query-with-2-linked-tables-and-1-aggregate-function-sum-cant-be-used)

Lien vers le commentaire
Partager sur d’autres sites

  • 2 months later...

En fait le problème n'est pas, à la base, le Cursor, mais le CursorAdapter, qui a besoin d'une colonne nommée _id dans la réponse du Cursor, pour pouvoir fonctionner.

Dans ton cas, tu n'as pas de telle colonne dans ton résultat (tes colonnes étant nommées 'transactions._id', 'utilisateurs._id' et 'utilisateurs.nom') (Ceci-dit, c'est le cas dans les deux exemples de requêtes que tu donnes, y compris celle qui fonctionne, ce qui est en contradiction avec mon explication... )

Tu peux peut-être résoudre ton problème en donnant des alias à tes colonnes de résultat.

Ce qui donnerai

return db.rawQuery("SELECT transactions._id as _id, utilisateurs._id as userId, SUM(transactions.montantTransaction) as total , utilisateurs.nomUtilisateur FROM transactions " +
                               "JOIN utilisateurs ON utilisateurs._id=transactions.idUtilisateurTransaction " +
                               "WHERE transactions.idUtilisateurTransaction=" + argument + " GROUP BY utilisateurs.nomUtilisateur, transactions._id, utilisateurs._id"
                               , null);

Merci chpil tu viens de me dépanner d'un lourd poids :P

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...