PowerGrid + PostgreSQL: „Spalte muss in der GROUP BY-Klausel erscheinen“, wenn nach Monat aggregiert wirdPhp

PHP-Programmierer chatten hier
Anonymous
 PowerGrid + PostgreSQL: „Spalte muss in der GROUP BY-Klausel erscheinen“, wenn nach Monat aggregiert wird

Post by Anonymous »

Ich verwende Laravel Livewire PowerGrid, um aggregierte Daten pro Monat aus meiner Ereignistabelle (PostgreSQL) anzuzeigen.
Ich möchte monatliche Summen berechnen:

Code: Select all

    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");
}
In meiner PowerGrid-Komponente habe ich Folgendes festgelegt:

Code: Select all

public string $primaryKey = 'month_key';
Und ich definiere die Spalten über transform() und Fields().
Beim Laden der Tabelle erhalte ich diesen PostgreSQL-Fehler:

Code: Select all

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)
Was ich versucht habe:
  • MIN(id) als ID hinzugefügt
  • PrimaryKey = 'month_key' setzen
    Zusätzliche Fragen:
Fragen:
  • Gibt es bessere Alternativen? zu PowerGrid für die Anzeige aggregierter Daten mit Laravel Livewire, insbesondere beim Umgang mit PostgreSQL und monatlichen Zusammenfassungen?
  • Gilt es im Allgemeinen als gute Praxis, Daten spontan auf diese Weise in der Datenquelle zu aggregieren, oder sollte ich aus Gründen der Leistung und Zuverlässigkeit eine VIEW oder MATERIALIZED VIEW verwenden?
Vollständiger Code:

Code: Select all

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, ',', ' ');
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post