Skip to content

Commit faeab8a

Browse files
feat: implement groupBy method for SQL queries and update tests (#404)
* feat: implement groupBy method for SQL queries and update related tests * test:remove skip tets * fix: correct customer name in SubQueryTest and update expected result count * remove backtick from test expectation --------- Co-authored-by: anggerpradana <75710827+anggerpradana@users.noreply.github.com>
1 parent 1508483 commit faeab8a

File tree

4 files changed

+55
-36
lines changed

4 files changed

+55
-36
lines changed

src/System/Database/MyQuery/Query.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ abstract class Query
5454
/**
5555
* Grouping.
5656
*
57-
* @var string|null
57+
* @var string[]
5858
*/
59-
protected $_group_by;
59+
protected $_group_by = [];
6060

6161
/**
6262
* Multy filter with strict mode.

src/System/Database/MyQuery/Select.php

+23
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,17 @@ public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC
172172
return $this;
173173
}
174174

175+
/**
176+
* Adds one or more columns to the
177+
* GROUP BY clause of the SQL query.
178+
*/
179+
public function groupBy(string ...$groups): self
180+
{
181+
$this->_group_by = $groups;
182+
183+
return $this;
184+
}
185+
175186
/**
176187
* Build SQL query syntac for bind in next step.
177188
*/
@@ -183,6 +194,7 @@ protected function builder(): string
183194

184195
$build['join'] = $this->joinBuilder();
185196
$build['where'] = $this->getWhere();
197+
$build['group_by'] = $this->getGroupBy();
186198
$build['sort_order'] = $this->_sort_order;
187199
$build['limit'] = $this->getLimit();
188200

@@ -209,6 +221,17 @@ private function getLimit(): string
209221
return "LIMIT $this->_limit_start, $this->_limit_end";
210222
}
211223

224+
private function getGroupBy(): string
225+
{
226+
if ([] === $this->_group_by) {
227+
return '';
228+
}
229+
230+
$group_by = implode(', ', $this->_group_by);
231+
232+
return "GROUP BY {$group_by}";
233+
}
234+
212235
public function sortOrderRef(int $limit_start, int $limit_end, int $offset, string $sort_ordder): void
213236
{
214237
$this->_limit_start = $limit_start;

tests/DataBase/Query/SelectTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,27 @@ public function itCanGenerateSelectWithSubQuery(): void
279279
'where exist query'
280280
);
281281
}
282+
283+
/** @test */
284+
public function itCanSelectWithGroupBy(): void
285+
{
286+
$select = MyQuery::from('test', $this->PDO)
287+
->select()
288+
->groupBy('culumn_1')
289+
;
290+
$select_multy = MyQuery::from('test', $this->PDO)
291+
->select()
292+
->groupBy('culumn_1', 'column_2')
293+
;
294+
295+
$this->assertEquals(
296+
'SELECT * FROM test GROUP BY culumn_1',
297+
$select->__toString()
298+
);
299+
300+
$this->assertEquals(
301+
'SELECT * FROM test GROUP BY culumn_1, column_2',
302+
$select_multy->__toString()
303+
);
304+
}
282305
}

tests/DataBase/RealDatabase/SubQueryTest.php

+7-34
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
use System\Database\MyQuery\Select;
1010
use System\Test\Database\BaseConnection;
1111

12-
use function System\Console\ok;
13-
1412
final class SubQueryTest extends BaseConnection
1513
{
1614
// scehema
@@ -209,8 +207,6 @@ public function itCanSelectSubQueryUsingWhere()
209207
*/
210208
public function itCanSelectSubQueryUsingFrom()
211209
{
212-
$this->markTestSkipped('this test requere select with group by statment');
213-
214210
$this->createUserSchema();
215211
$this->createOrderSchema();
216212
$this->createProductSchema();
@@ -220,23 +216,13 @@ public function itCanSelectSubQueryUsingFrom()
220216
$this->createProducts();
221217
$this->createSeles();
222218

223-
// SELECT sub.product_id, sub.total_quantity, sub.total_sales
224-
// FROM (
225-
// SELECT
226-
// product_id,
227-
// SUM(quantity) AS total_quantity,
228-
// SUM(quantity * price) AS total_sales
229-
// FROM sales
230-
// GROUP BY product_id
231-
// ) AS sub;
232-
233219
$products = new Select(
234220
new InnerQuery(
235-
new Select(
221+
(new Select(
236222
'sales',
237223
['product_id', 'SUM(quantity) AS total_quantity', 'SUM(quantity * price) AS total_sales'],
238224
$this->pdo
239-
),
225+
))->groupBy('product_id'),
240226
'sub'
241227
),
242228
['sub.product_id', 'sub.total_quantity', 'sub.total_sales'],
@@ -255,48 +241,35 @@ public function itCanSelectSubQueryUsingFrom()
255241
*/
256242
public function itCanSelectSubQueryUsingJoin(): void
257243
{
258-
$this->markTestSkipped('this test requere select with group by statment');
259-
260244
$this->createCustomerSchema();
261245
$this->createTransactionSchema();
262246
$this->createCustomers();
263247
$this->createTransactions();
264248

265-
// SELECT c.name, sub.total_spent
266-
// FROM customers c
267-
// JOIN (
268-
// SELECT customer_id, SUM(amount) AS total_spent
269-
// FROM transactions
270-
// GROUP BY customer_id
271-
// ) AS sub ON c.id = sub.customer_id
272-
// WHERE sub.total_spent > 500;
273-
274249
$customers = new Select(
275250
'customers',
276-
['costumer.name', 'sub.total_spent'],
251+
['customers.name', 'sub.total_spent'],
277252
$this->pdo
278253
);
279254

280255
$customers->join(
281256
InnerJoin::ref(
282257
new InnerQuery(
283-
new Select(
258+
(new Select(
284259
'transactions',
285260
['customer_id', 'SUM(amount) AS total_spent'],
286261
$this->pdo
287-
),
262+
))
263+
->groupBy('customer_id'),
288264
'sub'
289265
),
290266
'id',
291267
'customer_id'
292268
)
293269
);
294-
$customers->compare('total_spent', '>', 500);
295-
296-
ok($customers->__toString())->out();
297270

298271
$customers = $customers->get();
299272

300-
$this->assertCount(2, $customers);
273+
$this->assertCount(3, $customers);
301274
}
302275
}

0 commit comments

Comments
 (0)