Skip to content

Commit d218356

Browse files
committed
GroupedSelection: an aggregate over a group without rows returns null
max()/min()/sum() answered 0 for a group with no rows, which is a value the data never contained and which the plain Selection does not report either - it returns null there, like the SQL aggregate functions do for an empty set. count() keeps returning 0, it casts the result.
1 parent b77a19f commit d218356

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

src/Database/Table/GroupedSelection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public function aggregation(string $function, ?string $groupFunction = null): mi
136136
}
137137
}
138138

139-
return 0;
139+
return null; // the group has no rows, which is what the aggregate function would return for them
140140
}
141141

142142

tests/Database/Explorer/Explorer.aggregation.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ test('filtering groups by related count', function () use ($explorer) {
8080
], $bookTags);
8181
});
8282

83+
test('aggregation of a group without rows', function () use ($explorer) {
84+
$aggregates = [];
85+
foreach ($explorer->table('author') as $author) {
86+
$books = $author->related('book');
87+
$aggregates[$author->name] = [$books->count('*'), $books->max('id'), $books->min('id'), $books->sum('id')];
88+
}
89+
90+
// Geek has no books, so the aggregate functions have nothing to return but null; only count() is a number
91+
Assert::same([0, null, null, null], $aggregates['Geek']);
92+
Assert::same([2, 4, 3, 7], $aggregates['David Grudl']);
93+
});
94+
95+
8396
test('nested group by and having', function () use ($explorer) {
8497
$bookTags = [];
8598
foreach ($explorer->table('author') as $author) {

0 commit comments

Comments
 (0)