#php #laravel #eloquent #laravel-8
#php #ларавель #красноречивый #ларавель-8
Вопрос:
В настоящее время я работаю над извлечением данных с помощью group by, чтобы получить одно и то же имя сокровища, общее количество найденных и одинаковую сумму сокровищ (cap). Используя приведенный ниже код, я могу получить все данные о сокровищах, но когда сокровище полностью востребовано, оно не может показать, что total_left равен 0.
*заявленный столбец-это логическое значение, в котором 0 еще не заявлено. *шапка-это общее сокровище в одном и том же месте
Запрос
$treasure_hunt_data = TreasureHunt::where('claimed', '0') -gt;selectRaw(" treasure_name, count(claimed) as total_left, cap") -gt;groupBy(['treasure_name', 'cap']) -gt;get();
Данные
[ {"treasure_name":"Location A","total_left":5,"cap":5}, {"treasure_name":"Location B","total_left":2,"cap":2}, {"treasure_name":"Location C","total_left":2,"cap":2}, {"treasure_name":"Location D","total_left":10,"cap":10} ]
Желаемые Данные
[ {"treasure_name":"Location A","total_left":5,"cap":5}, {"treasure_name":"Location B","total_left":2,"cap":2}, {"treasure_name":"Location C","total_left":2,"cap":2}, {"treasure_name":"Location D","total_left":10,"cap":10}, {"treasure_name":"Location E","total_left":0,"cap":1} ]
Данные БД
Сведения о миграции
Schema::create('treasure_hunts', function (Blueprint $table) { $table-gt;id(); $table-gt;string('treasure_name'); $table-gt;boolean('claimed')-gt;default(0); $table-gt;string('cap'); $table-gt;timestamps(); });
Комментарии:
1. Пожалуйста, добавьте сведения о модели и миграции, а также примеры данных для желаемого вывода, чтобы у нас было представление о том, как выглядит ваша база данных.
2. @miken32, я добавил сведения о миграции и данные базы данных
3. Не публикуйте фотографии кода
Ответ №1:
Ниже приведены фактические записи в БД:
[{"id":1,"treasure_name":"Location A","claimed":1,"cap":"10","created_at":null,"updated_at":null}, {"id":2,"treasure_name":"Location B","claimed":1,"cap":"220","created_at":null,"updated_at":null}, {"id":3,"treasure_name":"Location C","claimed":1,"cap":"42","created_at":null,"updated_at":null}, {"id":4,"treasure_name":"Location D","claimed":0,"cap":"23","created_at":null,"updated_at":null}, {"id":5,"treasure_name":"Location A","claimed":1,"cap":"233","created_at":null,"updated_at":null}]
Попробуйте выполнить этот запрос, чтобы получить данные:
$treasure_hunt_data = TreasureHunt::select( 'treasure_name', DB::raw('sum(case when claimed = 1 then 1 else 0 end) as total_left'), DB::raw('sum(cap) as cap') ) -gt;groupBy('treasure_name') -gt;get();
Ниже приведены результаты вышеупомянутого запроса:
[{"treasure_name":"Location A","total_left":"2","cap":243}, {"treasure_name":"Location B","total_left":"1","cap":220}, {"treasure_name":"Location C","total_left":"1","cap":42}, {"treasure_name":"Location D","total_left":"0","cap":23}]
Комментарии:
1. Да, это работа, но нужно внести в нее некоторые изменения
Ответ №2:
Вы можете сделать это с помощью CTE (Общее табличное выражение) и DB::select
оператора. Например:
$treasure_hunt_data = DB::select(" with treasure_data as ( select treasure_name, count(claimed) as total_left, cap from treasure_hunt where claimed = 0 group by treasure_name, cap ) select * from treasure_data where total_left = 0 ");
Который вернет результирующий набор в виде массива.
Комментарии:
1. Возврата данных не будет, если мы используем where total_left = 0; без where total_left = 0; мы получим [{«имя_ сокровищницы»:»Местоположение A»,»тотальное_ оставление»:5,»ограничение»:5}, {«имя_ сокровищницы»:»Местоположение B»,»тотальное_ оставление»:2,»ограничение»:2}, {«имя_ сокровищницы»:»Местоположение C»,»тотальное_ оставление»:2,»ограничение»:2}, {«имя_ сокровищницы»:»Местоположение D»,»total_left»:10,»ограничение»:10}]
2. Отредактируйте CTE по мере необходимости, просто для примера.