Comment sélectionner à partir de la sous-requête à l'aide de Laravel Générateur de Requêtes?
J'aimerais obtenir la valeur par la suite SQL à l'aide de Éloquent ORM.
- SQL
SELECT COUNT(*) FROM
(SELECT * FROM abc GROUP BY col1) AS a;
Ensuite, j'ai examiné les questions suivantes.
- Code
$sql = Abc::from('abc AS a')->groupBy('col1')->toSql();
$num = Abc::from(\DB::raw($sql))->count();
print $num;
Je suis à la recherche d'une meilleure solution.
Il vous plaît dites-moi la solution la plus simple.
Vous devez vous connecter pour publier un commentaire.
En plus de @delmadord de réponse et de vos commentaires:
Actuellement, il n'existe pas de méthode permettant de créer une sous-requête dans
FROM
clause, de sorte que vous devez manuellement utilisation de raw déclaration, puis, si nécessaire, vous allez fusionner toutes les liaisons:L'esprit que vous devez fusion des liaisons dans l'ordre correct. Si vous avez d'autres liés clauses, vous devez les placer après
mergeBindings
:Argument 1 passed to Illuminate\Database\Query\Builder::mergeBindings() must be an instance of Illuminate\Database\Query\Builder, instance of Illuminate\Database\Eloquent\Builder given
, qu'ai-je manqué?$sub->getQuery()
partie, qui obtient le sous-jacentQuery\Builder
objet.belongsToMany
comme-ci vous devez ajoutergetQuery()
deux fois =>$sub->getQuery()->getQuery()
?
aop espaces réservés comme d'habitude - il y amergeBindings
partie qui gère leurs valeurs réelles. Pour résumer - non, c'est sql-injection de sécurité dans ce formulaire.$sub->getQuery()->toSql()
se traduit par pure instruction SQL, donc si il n'y a aucune entrée d'utilisateur, il est vulnérable parce que je suis sur qu'à l'intérieur deDB::raw($sub->getQuery()->toSql())
qui n'échappe pas à quoi que ce soit.$sub
requête est créée avec une bonne Éloquent, puis quand il est converti avectoSql()
il sera échappé, puisque les valeurs sont la bande correctement? Même si je n'utilise pas mergeBindings mais seulement à l'aide detoSql()
à l'intérieur de DB::raw tous seraient en sécurité?toSql
. Lisez à propos de PDO php.net/manual/en/book.pdo.php et de voir le résultat de votre$query->toSql()
$sub
requête est un Éloquent Builder, vous avez encore besoin de la->getQuery()
partie, sinon vous obtenez l'erreur, puisque cette méthode est typehinted contreQuery\Builder
classe.Laravel v5.6.12 (2018-03-14) ajouté
fromSub()
etfromRaw()
méthodes dans le générateur de requêtes (#23476).Accepté la réponse est correcte, mais peut être simplifiée en:
L'extrait ci-dessus génère le code SQL suivant:
La solution de @JarekTkaczyk c'est exactement ce que je cherchais. La seule chose qui me manque c'est comment le faire lorsque vous êtes à l'aide de
DB::table()
requêtes. Dans ce cas, c'est comment je le fais:Spéciale attention comment faire de la
mergeBindings
sans l'aide de lagetQuery()
méthodeDe laravel 5.5 il y a une méthode spécifique pour les sous-requêtes et vous pouvez l'utiliser comme ceci:
Abc::selectSub(function($q) { $q->select('*')->groupBy('col1'); }, 'a')->count('a.*');
ou
Abc::selectSub(Abc::select('*')->groupBy('col1'), 'a')->count('a.*');
Call to undefined method subSelect()
semblesubSelect
n'existe pas.selectSub
. J'ai mis à jour ma réponse maintenant.Je ne pouvais pas fait votre code pour faire la requête souhaitée, est un alias de la table
abc
, pas pour la table dérivée.Laravel Générateur de Requête n'est pas implicitement de soutien provenant des alias de table, DB::raw est probablement nécessaire pour cela.
La plus simple solution je pourrais venu avec est presque identique à la vôtre, cependant produit de la requête, comme vous l'avez demandé:
Le produit de la requête est
J'aime faire quelque chose comme ceci:
Ce n'est pas très élégant, mais c'est simple.