Eloquent ORMを使用して、次のSQLで値を取得したいと思います。
-SQL
SELECT COUNT(*) FROM
(SELECT * FROM abc GROUP BY col1) AS a;
それから私は次のことを考えました。
-コード
$sql = Abc::from('abc AS a')->groupBy('col1')->toSql();
$num = Abc::from(\DB::raw($sql))->count();
print $num;
より良い解決策を探しています。
最も簡単な解決策を教えてください。
@delmadordの回答とコメントに加えて:
現在、FROM
句にサブクエリを作成する方法がないため、生のステートメントを手動で使用する必要があり、必要に応じて、すべてのバインディングをマージします。
$sub = Abc::where(..)->groupBy(..); // Eloquent Builder instance
$count = DB::table( DB::raw("({$sub->toSql()}) as sub") )
->mergeBindings($sub->getQuery()) // you need to get underlying Query Builder
->count();
バインディングを正しい順序でマージする必要があることに注意してください。他のバインド句がある場合は、mergeBindings
の後に配置する必要があります。
$count = DB::table( DB::raw("({$sub->toSql()}) as sub") )
// ->where(..) wrong
->mergeBindings($sub->getQuery()) // you need to get underlying Query Builder
// ->where(..) correct
->count();
Laravel v5.6.12(2018-03-14)クエリビルダーにfromSub()
およびfromRaw()
メソッドを追加 (#23476) .
受け入れられた答えは正しいですが、次のように簡略化できます。
DB::query()->fromSub(function ($query) {
$query->from('abc')->groupBy('col1');
}, 'a')->count();
上記のスニペットは、次のSQLを生成します。
select count(*) as aggregate from (select * from `abc` group by `col1`) as `a`
@JarekTkaczykのソリューションは、まさに私が探していたものです。 DB::table()
クエリを使用しているときに、それを行う方法だけが見逃します。この場合、これは私がそれを行う方法です:
$other = DB::table( DB::raw("({$sub->toSql()}) as sub") )->select(
'something',
DB::raw('sum( qty ) as qty'),
'foo',
'bar'
);
$other->mergeBindings( $sub );
$other->groupBy('something');
$other->groupBy('foo');
$other->groupBy('bar');
print $other->toSql();
$other->get();
getQuery()
メソッドを使用せずにmergeBindings
を作成する方法に特に注意してください
laravel 5.5から、サブクエリ専用のメソッドがあり、次のように使用できます。
Abc::selectSub(function($q) { $q->select('*')->groupBy('col1'); }, 'a')->count('a.*');
または
Abc::selectSub(Abc::select('*')->groupBy('col1'), 'a')->count('a.*');
目的のクエリを実行するコードを作成できませんでした。ASは、派生テーブルではなく、テーブルabc
のみのエイリアスです。 Laravel Query Builderは、派生テーブルエイリアスを暗黙的にサポートしていません。これにはDB :: rawが必要になる可能性が高いです。
私が思いついた最も簡単な解決策はあなたのものとほとんど同じですが、あなたが求めたようにクエリを生成します:
$sql = Abc::groupBy('col1')->toSql();
$count = DB::table(DB::raw("($sql) AS a"))->count();
生成されたクエリは
select count(*) as aggregate from (select * from `abc` group by `col1`) AS a;
私はこのようなことをするのが好きです:
Message::select('*')
->from(DB::raw("( SELECT * FROM `messages`
WHERE `to_id` = ".Auth::id()." AND `isseen` = 0
GROUP BY `from_id` asc) as `sub`"))
->count();
あまりエレガントではありませんが、シンプルです。