Я хочу рассчитать ежемесячные суммы:
public function datasource(): Builder
{
return DB::table('events')
->whereNotNull('date')
->selectRaw("
MIN(id) as id,
to_char(date, 'YYYY-MM') as month_key,
ROUND(SUM(COALESCE(total_cost, 0))::numeric, 2) as total_cost_sum,
ROUND(SUM(COALESCE(implementation_1c, 0))::numeric, 2) as implementation_sum
")
->groupByRaw("to_char(date, 'YYYY-MM')")
->orderByRaw("to_char(date, 'YYYY-MM') DESC");
}
В моем компоненте PowerGrid я установил:
public string $primaryKey = 'month_key';
И я определяю столбцы с помощью Transform() и полей().
При загрузке таблицы я получаю следующую ошибку PostgreSQL:
SQLSTATE[42803]: Grouping error: 7 ERROR: column "events.id" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: ... 'YYYY-MM') order by to_char(date, 'YYYY-MM') DESC, "id" asc ^ (Connection: pgsql, SQL: select count(*) as aggregate from "events" where "date" is not null group by to_char(date, 'YYYY-MM') order by to_char(date, 'YYYY-MM') DESC, "id" asc)
Что я пробовал:
- Добавил MIN(id) в качестве идентификатора
- Установил PrimaryKey = 'month_key'
Дополнительные вопросы:
- Есть ли лучше альтернативы PowerGrid для отображения агрегированных данных с помощью Laravel Livewire, особенно при работе с PostgreSQL и ежемесячными сводками?
- В целом, считается ли хорошей практикой агрегировать данные на лету в источнике данных подобным образом, или мне следует использовать VIEW или MATERIALIZED VIEW для производительности и надежности?
final class EventsMonthlyTable extends PowerGridComponent
{
public string $tableName = 'events-monthly-table';
public string $primaryKey = 'month_key';
public function setUp(): array
{
return [
PowerGrid::header()
->showSearchInput(),
PowerGrid::footer()
->showPerPage(false)
->showRecordCount(),
PowerGrid::detail()
->view('components.events.monthly-detail')
->showCollapseIcon()
->params(['stub' => true]),
];
}
public function datasource(): Builder
{
return DB::table('events')
->whereNotNull('date')
->selectRaw("
MIN(id) as id,
to_char(date, 'YYYY-MM') as month_key,
ROUND(SUM(COALESCE(total_cost, 0))::numeric, 2) as total_cost_sum,
ROUND(SUM(COALESCE(implementation_1c, 0))::numeric, 2) as implementation_sum
")
->groupByRaw("to_char(date, 'YYYY-MM')")
->orderByRaw("to_char(date, 'YYYY-MM') DESC");
}
public function fields(): PowerGridFields
{
return PowerGrid::fields()
->add('month')
->add('total_cost_formatted')
->add('implementation_formatted');
}
public function columns(): array
{
return [
Column::make('month', 'month')
->sortable(),
Column::make('total_cost_formatted', 'total_cost_formatted')
->sortable(),
Column::make('implementation_formatted', 'implementation_formatted')
->sortable(),
];
}
public function transform($row): array
{
return [
'month' => Carbon::createFromFormat('Y-m', $row->month_key)
->translatedFormat('F Y'),
'total_cost_formatted' => $this->formatMoney($row->total_cost_sum),
'implementation_formatted' => $this->formatMoney($row->implementation_sum),
];
}
private function formatMoney(float $value): string
{
return number_format($value, 2, ',', ' ');
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... en-aggrega
Мобильная версия