web-dev-qa-db-fra.com

DB-> count () retournant une valeur différente de count (DB-> get ())

J'ai la plus simple des requêtes que j'essaie d'exécuter

DB::table('user_visits')->groupBy('user_id')->count();

Mais il renvoie le mauvais numéro, 8.

Si je le change en ceci:

count(DB::table('user_visits')->groupBy('user_id')->get());

Ensuite, il renvoie le nombre correct, 34. Pourquoi ne s'agit-il pas de la même valeur?

Voici ma structure de table

user_visits( user_id, date_visited, num_clicks )
9
andrewtweber

ne note sur le débogage
Les requêtes générées par ces deux approches différentes sont complètement différentes, et c'est pourquoi cela vous arrive. Chaque fois que vous rencontrez des problèmes de base de données, c'est toujours une bonne idée de consulter le journal de requête sous-jacent, afin que vous puissiez voir ce qui est exécuté en faisant:

dd(DB::getQueryLog());

qui imprimera le journal des requêtes, si vous le faites juste après les recherches incriminées, vous pouvez simplement aller à la fin du journal pour votre dernière requête (c'est-à-dire si vous l'avez placé après la deuxième recherche, la dernière requête dans le journal serait être votre compteur encapsulé, et la dernière mais une seule requête serait la méthode de comptage).

Votre problème spécifique
Quoi qu'il en soit, pour expliquer votre problème spécifique. Les deux requêtes générées seront comme

DB::table('user_visits')->groupBy('user_id')->count();
// SELECT COUNT(*) from user_visits GROUP BY user_id

Cela renverra le nombre d'entrées dans chaque groupe. Ce que fait mysql, c'est de regrouper toutes les lignes par la colonne user_id, puis de retourner une ligne par groupe avec les nombres. Si nous avons ajouté le "user_id" dans les colonnes pour la sélection et exécuté la requête manuellement sur votre base de données, vous pourriez voir quelque chose comme ceci en résultat

// SELECT user_id, COUNT(*) FROM user_visits GROUP BY user_id

----------------------
| user_id | COUNT(*) |
----------------------
| 1       | 8        |
| 2       | 4        |
| 5       | 11       |
----------------------

Votre deuxième requête est différente

DB::table('user_visits')->groupBy('user_id')->get()
// SELECT * FROM user_visits GROUP BY user_id

Ce que cela fait, c'est simplement sélectionner toutes les entrées, les regrouper et les renvoyer. Il en résulte une ligne par ID utilisateur renvoyée et cette ligne contient toutes les informations pour UNE des entrées de cet utilisateur_id (il peut s'agir de la première entrée pour cet utilisateur, ce peut être la dernière, elle peut être aléatoire , cela n'a pas d'importance cependant).

Votre count() compte alors le nombre de lignes renvoyées, qui sera le nombre d'id_utilisateur uniques.

Ainsi, votre première requête compte le nombre d'ID utilisateur par groupe (et laravel renverra le premier enregistrement lorsque vous essayez d'imprimer le résultat, ce qui entraîne l'affichage du nombre d'entrées pour le premier ID utilisateur) dans le jeu de résultats), et votre deuxième requête (plus la fonction de comptage appliquée) renvoie le nombre de groupes trouvés (c'est-à-dire le nombre d'ID utilisateur uniques).

En utilisant mon tableau ci-dessus, pour illustrer cela ...

Requête 1: renvoie "8", car il s'agit du nombre, pour la première entrée du jeu de résultats
Requête 2: renvoie "3", car il s'agit du nombre, pour le nombre de lignes du jeu de résultats

Vous voulez le bon numéro, sans charger toutes les données?
Si vous voulez le résultat correct selon votre deuxième requête, mais que vous voulez la réponse en un seul entier légère et moins lourde du réseau de la requête 1, vous pouvez le faire:

DB::table('user_invites')->count(DB::raw('DISTINCT user_id'))

ce qui se traduit par:

SELECT COUNT(DISTINCT user_id) FROM user_visits;

J'espère que tout a du sens, c'est un peu déroutant de se mettre dans la tête, je suis sûr

32
Lee

Vous pouvez essayer ceci parce que le group by l'instruction est exécutée après le count ( Bug # 26209 ):

DB::table('user_visits')->distinct('user_id')->count('user_id');

Un autre réponse mySql ici.

3
The Alpha