Подтвердить что ты не робот

Как выбрать из подзапроса с помощью Laravel Query Builder?

Я хотел бы получить значение по следующему SQL, используя Eloquent ORM.

- 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;

Я ищу лучшее решение.

Скажите, пожалуйста, простейшее решение.

4b9b3361

Ответ 1

В дополнение к ответу @delmadord и вашим комментариям:

В настоящее время нет способа создания подзапроса в FROM, поэтому вам нужно вручную использовать команду raw, а затем, если необходимо, вы слейте все привязки:

$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();

Ответ 2

Решение @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();

Особое внимание, как сделать mergeBindings без использования метода getQuery()

Ответ 3

Мне нравится делать что-то вроде этого:

Message::select('*')
->from(DB::raw("( SELECT * FROM `messages`
                  WHERE `to_id` = ".Auth::id()." AND `isseen` = 0
                  GROUP BY `from_id` asc) as `sub`"))
->count();

Это не очень элегантно, но просто.

Ответ 4

Я не мог заставить ваш код делать желаемый запрос, 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;

Ответ 5

Вам нужен суб-запрос? Вы можете попробовать что-то вроде

$num = Abc::groupBy('col1')->get()->count();

Не идеально, если у вас есть миллионы строк.