Fix aggregation: proper DATE_FORMAT, escaped %
This commit is contained in:
parent
606ae60db8
commit
3575e1843e
|
|
@ -48,12 +48,20 @@ class ServerDetailController extends Model
|
||||||
|
|
||||||
// Запрос с агрегацией если нужно
|
// Запрос с агрегацией если нужно
|
||||||
if ($groupBy) {
|
if ($groupBy) {
|
||||||
|
// Используем агрегацию на основе aggregate_minutes
|
||||||
|
$bucketFormat = match(true) {
|
||||||
|
// Экранируем % для DATE_FORMAT
|
||||||
|
$aggConfig['aggregate_minutes'] >= 60 => '%Y-%m-%d %H:00', // 1 hour+
|
||||||
|
$aggConfig['aggregate_minutes'] >= 15 => '%Y-%m-%d %H:%i', // 15-59 min
|
||||||
|
default => '%Y-%m-%d %H:%i:00' // 1-14 min
|
||||||
|
};
|
||||||
|
|
||||||
$sql = "
|
$sql = "
|
||||||
SELECT
|
SELECT
|
||||||
AVG(sm.value) as value,
|
AVG(sm.value) as value,
|
||||||
mn.name,
|
mn.name,
|
||||||
mn.unit,
|
mn.unit,
|
||||||
DATE_FORMAT(sm.created_at, '%Y-%m-%d %H:%i:00') as time_bucket
|
DATE_FORMAT(sm.created_at, '{$bucketFormat}') as time_bucket
|
||||||
FROM server_metrics sm
|
FROM server_metrics sm
|
||||||
JOIN metric_names mn ON sm.metric_name_id = mn.id
|
JOIN metric_names mn ON sm.metric_name_id = mn.id
|
||||||
WHERE sm.server_id = :id
|
WHERE sm.server_id = :id
|
||||||
|
|
@ -144,21 +152,27 @@ class ServerDetailController extends Model
|
||||||
|
|
||||||
private function getAggregationConfig(string $period, ?string $zoom): array
|
private function getAggregationConfig(string $period, ?string $zoom): array
|
||||||
{
|
{
|
||||||
|
// Target: ~200-400 points on chart regardless of period
|
||||||
|
|
||||||
if ($zoom) {
|
if ($zoom) {
|
||||||
return match($zoom) {
|
return match($zoom) {
|
||||||
'1h' => ['interval' => 'INTERVAL 1 HOUR', 'groupBy' => null],
|
// Short periods - show all points
|
||||||
'6h' => ['interval' => 'INTERVAL 6 HOUR', 'groupBy' => null],
|
'1h' => ['interval' => 'INTERVAL 1 HOUR', 'groupBy' => null, 'aggregate_minutes' => 0],
|
||||||
'24h' => ['interval' => 'INTERVAL 24 HOUR', 'groupBy' => null],
|
'6h' => ['interval' => 'INTERVAL 6 HOUR', 'groupBy' => null, 'aggregate_minutes' => 0],
|
||||||
'7d' => ['interval' => 'INTERVAL 7 DAY', 'groupBy' => "GROUP BY mn.id, time_bucket"],
|
// Medium period - light aggregation
|
||||||
'30d' => ['interval' => 'INTERVAL 30 DAY', 'groupBy' => "GROUP BY mn.id, time_bucket"],
|
'24h' => ['interval' => 'INTERVAL 24 HOUR', 'groupBy' => "GROUP BY mn.id, DATE_FORMAT(sm.created_at, '%Y-%m-%d %H:%i')", 'aggregate_minutes' => 1],
|
||||||
default => ['interval' => 'INTERVAL 24 HOUR', 'groupBy' => null]
|
// Long periods - strong aggregation
|
||||||
|
'7d' => ['interval' => 'INTERVAL 7 DAY', 'groupBy' => "GROUP BY mn.id, DATE_FORMAT(sm.created_at, '%Y-%m-%d %H:%i')", 'aggregate_minutes' => 15],
|
||||||
|
'30d' => ['interval' => 'INTERVAL 30 DAY', 'groupBy' => "GROUP BY mn.id, DATE_FORMAT(sm.created_at, '%Y-%m-%d %H:00')", 'aggregate_minutes' => 60],
|
||||||
|
default => ['interval' => 'INTERVAL 24 HOUR', 'groupBy' => null, 'aggregate_minutes' => 0]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default: base period aggregation
|
||||||
return match($period) {
|
return match($period) {
|
||||||
'7d' => ['interval' => 'INTERVAL 7 DAY', 'groupBy' => "GROUP BY mn.id, time_bucket"],
|
'7d' => ['interval' => 'INTERVAL 7 DAY', 'groupBy' => "GROUP BY mn.id, DATE_FORMAT(sm.created_at, '%Y-%m-%d %H:%i')", 'aggregate_minutes' => 15],
|
||||||
'30d' => ['interval' => 'INTERVAL 30 DAY', 'groupBy' => "GROUP BY mn.id, time_bucket"],
|
'30d' => ['interval' => 'INTERVAL 30 DAY', 'groupBy' => "GROUP BY mn.id, DATE_FORMAT(sm.created_at, '%Y-%m-%d %H:00')", 'aggregate_minutes' => 60],
|
||||||
default => ['interval' => 'INTERVAL 24 HOUR', 'groupBy' => null]
|
default => ['interval' => 'INTERVAL 24 HOUR', 'groupBy' => null, 'aggregate_minutes' => 0]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue