Skip to content

Commit 6bf5c06

Browse files
authored
feat(database): add having and groupBy in select query builder (#1370)
1 parent 21ca22c commit 6bf5c06

File tree

4 files changed

+59
-7
lines changed

4 files changed

+59
-7
lines changed

packages/database/src/Builder/QueryBuilders/SelectQueryBuilder.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
use Tempest\Database\OnDatabase;
1212
use Tempest\Database\Query;
1313
use Tempest\Database\QueryStatements\FieldStatement;
14+
use Tempest\Database\QueryStatements\GroupByStatement;
1415
use Tempest\Database\QueryStatements\HasWhereStatements;
16+
use Tempest\Database\QueryStatements\HavingStatement;
1517
use Tempest\Database\QueryStatements\JoinStatement;
1618
use Tempest\Database\QueryStatements\OrderByStatement;
1719
use Tempest\Database\QueryStatements\RawStatement;
@@ -123,6 +125,24 @@ public function orderBy(string $statement): self
123125
return $this;
124126
}
125127

128+
/** @return self<TModelClass> */
129+
public function groupBy(string $statement): self
130+
{
131+
$this->select->groupBy[] = new GroupByStatement($statement);
132+
133+
return $this;
134+
}
135+
136+
/** @return self<TModelClass> */
137+
public function having(string $statement, mixed ...$bindings): self
138+
{
139+
$this->select->having[] = new HavingStatement($statement);
140+
141+
$this->bind(...$bindings);
142+
143+
return $this;
144+
}
145+
126146
/** @return self<TModelClass> */
127147
public function limit(int $limit): self
128148
{

packages/database/src/QueryStatements/SelectStatement.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,6 @@ public function compile(DatabaseDialect $dialect): string
5454
->implode(PHP_EOL);
5555
}
5656

57-
if ($this->orderBy->isNotEmpty()) {
58-
$query[] = 'ORDER BY ' . $this->orderBy
59-
->map(fn (OrderByStatement $orderBy) => $orderBy->compile($dialect))
60-
->implode(', ');
61-
}
62-
6357
if ($this->groupBy->isNotEmpty()) {
6458
$query[] = 'GROUP BY ' . $this->groupBy
6559
->map(fn (GroupByStatement $groupBy) => $groupBy->compile($dialect))
@@ -72,6 +66,12 @@ public function compile(DatabaseDialect $dialect): string
7266
->implode(PHP_EOL);
7367
}
7468

69+
if ($this->orderBy->isNotEmpty()) {
70+
$query[] = 'ORDER BY ' . $this->orderBy
71+
->map(fn (OrderByStatement $orderBy) => $orderBy->compile($dialect))
72+
->implode(', ');
73+
}
74+
7575
if ($this->limit !== null) {
7676
$query[] = 'LIMIT ' . $this->limit;
7777
}

packages/database/tests/QueryStatements/SelectStatementTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public function test_select(): void
3838
FROM `foo` AS `bar`
3939
INNER JOIN foo ON bar.id = foo.id
4040
WHERE `foo` = "bar"
41-
ORDER BY `foo` DESC
4241
GROUP BY `foo`
4342
HAVING `foo` = "bar"
43+
ORDER BY `foo` DESC
4444
LIMIT 10
4545
OFFSET 100
4646
SQL;

tests/Integration/Database/Builder/SelectQueryBuilderTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,38 @@ public function test_eager_loads_combined_with_manual_loads(): void
409409
SQL, $query);
410410
}
411411

412+
public function test_group_by(): void
413+
{
414+
$sql = query('authors')
415+
->select()
416+
->groupBy('name')
417+
->toSql();
418+
419+
$expected = <<<SQL
420+
SELECT *
421+
FROM authors
422+
GROUP BY name
423+
SQL;
424+
425+
$this->assertSameWithoutBackticks($expected, $sql);
426+
}
427+
428+
public function test_having(): void
429+
{
430+
$sql = query('authors')
431+
->select()
432+
->having('name = ?', 'Brent')
433+
->toSql();
434+
435+
$expected = <<<SQL
436+
SELECT *
437+
FROM authors
438+
HAVING name = ?
439+
SQL;
440+
441+
$this->assertSameWithoutBackticks($expected, $sql);
442+
}
443+
412444
private function seed(): void
413445
{
414446
$this->migrate(

0 commit comments

Comments
 (0)