web-dev-qa-db-fra.com

Laravel Eloquent - distinct () et count () ne fonctionnent pas correctement ensemble

J'essaie donc d'obtenir le nombre de pid distincts sur une requête, mais la valeur renvoyée est fausse.

C'est ce que j'essaie de faire:

$ad->getcodes()->groupby('pid')->distinct()->count()

ce qui retourne la valeur "2", alors que la valeur à renvoyer devrait être "1".

En guise de solution de contournement, je fais ceci:

count($ad->getcodes()->groupby('pid')->distinct()->get())

ce qui fonctionne bien et renvoie "1"

Existe-t-il une règle où count et distinct ne peuvent pas être sur la même requête? Je trouve la solution de contournement du type "lourd", je voudrais faire fonctionner la requête originale :(

63
Inigo EC

Ce qui suit devrait fonctionner

$ad->getcodes()->distinct('pid')->count('pid');
72
Suresh Bala

Quelqu'un d'autre trouve ce post, et ne trouve pas les autres suggestions pour travailler?

En fonction de la requête spécifique, une approche différente peut être nécessaire. Dans mon cas, je devais soit compter les résultats d’un GROUP BY, par exemple.

SELECT COUNT(*) FROM (SELECT * FROM a GROUP BY b)

ou utilisez COUNT(DISTINCT b):

SELECT COUNT(DISTINCT b) FROM a

Après avoir réfléchi, j'ai réalisé qu'il n'y avait pas de fonction Laravel intégrée pour cela. La solution la plus simple consistait donc à utiliser DB::raw avec la méthode count.

$count = $builder->count(DB::raw('DISTINCT b'));

Rappelez-vous, n'utilisez pas groupBy avant d'appeler count. Vous pouvez appliquer groupBy plus tard, si vous en avez besoin pour obtenir des lignes.

10
Zoon

Une réponse plus générique qui m'aurait permis de gagner du temps et, espérons-le, d'autres:

Ne fonctionne pas (renvoie le nombre de toutes les lignes):

DB::table('users')
            ->select('first_name')
            ->distinct()
            ->count();

Le correctif:

DB::table('users')
            ->distinct()
            ->count('first_name');
8
Andrew

J'ai eu un problème similaire et j'ai trouvé un moyen de le contourner.

Le problème est la façon dont le générateur de requêtes de Laravel gère les agrégats. Il prend le premier résultat renvoyé, puis renvoie la valeur "agrégée". Cela convient généralement bien, mais lorsque vous combinez le nombre avec groupBy, vous retournez un nombre par élément groupé. Donc, l'agrégat de la première rangée est juste un compte du premier groupe (donc un peu bas comme 1 ou 2 est probable).

Le compte de Laravel est donc sorti, mais j'ai combiné le constructeur de requêtes Laravel avec du SQL brut pour obtenir un compte précis de mes résultats groupés.

Pour votre exemple, je suppose que les éléments suivants devraient fonctionner (et vous permettent d'éviter l'obtenir):

$query = $ad->getcodes()->groupby('pid')->distinct();
$count = count(\DB::select($query->toSql(), $query->getBindings()));

Si vous voulez vous assurer que vous ne perdez pas de temps à sélectionner toutes les colonnes, vous pouvez éviter cela lors de la construction de votre requête:

 $query = $ad->select(DB::raw(1))->getcodes()->groupby('pid')->distinct();
3
Matt McDonald

Est-ce que ça ne marcherait pas?

$ad->getcodes()->distinct()->get(['pid'])->count();

Voir ici pour discussion ..

1
JonnyFoley

Distinct ne prend pas d'arguments, car il ajoute DISTINCT dans votre requête SQL. Toutefois, vous pouvez avoir besoin de définir le nom de la colonne avec laquelle vous souhaitez sélectionner distinct. Ainsi, si vous avez Flight->select('project_id')->distinct()->get() est équivalent à SELECT DISTINCT 'project_id' FROM flights et vous pouvez maintenant ajouter d’autres modificateurs tels que count () ou même des requêtes éloquentes brutes.

0

Je suis tombé sur le même problème. 

Si vous installez la barre de débogage de laravel, vous pouvez voir les requêtes et souvent voir le problème

$ad->getcodes()->groupby('pid')->distinct()->count()

changer à 

$ad->getcodes()->distinct()->select('pid')->count()

Vous devez définir les valeurs à renvoyer comme distinctes. Si vous ne définissez pas les champs de sélection, toutes les colonnes de la base de données seront renvoyées et toutes seront uniques. Définissez donc la requête sur distinct et sélectionnez uniquement les colonnes qui constituent votre valeur «distincte» que vous souhaitez ajouter davantage. ->select('pid','date') pour obtenir toutes les valeurs uniques d'un utilisateur en une journée

0
Brett
$solution = $query->distinct()
            ->groupBy
            (
                [
                    'array',
                    'of',
                    'columns',
                ]
            )
            ->addSelect(
                [
                    'columns',
                    'from',
                    'the',
                    'groupby',
                ]
            )
            ->get();

Rappelez-vous que le groupe par est facultatif, cela devrait fonctionner dans la plupart des cas, si vous souhaitez qu'un groupe de comptes exclue les valeurs de sélection dupliquées, la méthode addSelect est une méthode d'instance querybuilder.

0
Daniel Santos
DB::table('adverts')->distinct()->select('ad_advertiser')->get()
0
Gurpreet Singh