Skip to content

Commit

Permalink
feat: implement groupBy method for SQL queries and update tests (#404)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
SonyPradana and anggerpradana authored Jan 2, 2025
1 parent 1508483 commit faeab8a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 36 deletions.
4 changes: 2 additions & 2 deletions src/System/Database/MyQuery/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ abstract class Query
/**
* Grouping.
*
* @var string|null
* @var string[]
*/
protected $_group_by;
protected $_group_by = [];

/**
* Multy filter with strict mode.
Expand Down
23 changes: 23 additions & 0 deletions src/System/Database/MyQuery/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ public function order(string $column_name, int $order_using = MyQuery::ORDER_ASC
return $this;
}

/**
* Adds one or more columns to the
* GROUP BY clause of the SQL query.
*/
public function groupBy(string ...$groups): self
{
$this->_group_by = $groups;

return $this;
}

/**
* Build SQL query syntac for bind in next step.
*/
Expand All @@ -183,6 +194,7 @@ protected function builder(): string

$build['join'] = $this->joinBuilder();
$build['where'] = $this->getWhere();
$build['group_by'] = $this->getGroupBy();
$build['sort_order'] = $this->_sort_order;
$build['limit'] = $this->getLimit();

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

private function getGroupBy(): string
{
if ([] === $this->_group_by) {
return '';
}

$group_by = implode(', ', $this->_group_by);

return "GROUP BY {$group_by}";
}

public function sortOrderRef(int $limit_start, int $limit_end, int $offset, string $sort_ordder): void
{
$this->_limit_start = $limit_start;
Expand Down
23 changes: 23 additions & 0 deletions tests/DataBase/Query/SelectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,27 @@ public function itCanGenerateSelectWithSubQuery(): void
'where exist query'
);
}

/** @test */
public function itCanSelectWithGroupBy(): void
{
$select = MyQuery::from('test', $this->PDO)
->select()
->groupBy('culumn_1')
;
$select_multy = MyQuery::from('test', $this->PDO)
->select()
->groupBy('culumn_1', 'column_2')
;

$this->assertEquals(
'SELECT * FROM test GROUP BY culumn_1',
$select->__toString()
);

$this->assertEquals(
'SELECT * FROM test GROUP BY culumn_1, column_2',
$select_multy->__toString()
);
}
}
41 changes: 7 additions & 34 deletions tests/DataBase/RealDatabase/SubQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
use System\Database\MyQuery\Select;
use System\Test\Database\BaseConnection;

use function System\Console\ok;

final class SubQueryTest extends BaseConnection
{
// scehema
Expand Down Expand Up @@ -209,8 +207,6 @@ public function itCanSelectSubQueryUsingWhere()
*/
public function itCanSelectSubQueryUsingFrom()
{
$this->markTestSkipped('this test requere select with group by statment');

$this->createUserSchema();
$this->createOrderSchema();
$this->createProductSchema();
Expand All @@ -220,23 +216,13 @@ public function itCanSelectSubQueryUsingFrom()
$this->createProducts();
$this->createSeles();

// SELECT sub.product_id, sub.total_quantity, sub.total_sales
// FROM (
// SELECT
// product_id,
// SUM(quantity) AS total_quantity,
// SUM(quantity * price) AS total_sales
// FROM sales
// GROUP BY product_id
// ) AS sub;

$products = new Select(
new InnerQuery(
new Select(
(new Select(
'sales',
['product_id', 'SUM(quantity) AS total_quantity', 'SUM(quantity * price) AS total_sales'],
$this->pdo
),
))->groupBy('product_id'),
'sub'
),
['sub.product_id', 'sub.total_quantity', 'sub.total_sales'],
Expand All @@ -255,48 +241,35 @@ public function itCanSelectSubQueryUsingFrom()
*/
public function itCanSelectSubQueryUsingJoin(): void
{
$this->markTestSkipped('this test requere select with group by statment');

$this->createCustomerSchema();
$this->createTransactionSchema();
$this->createCustomers();
$this->createTransactions();

// SELECT c.name, sub.total_spent
// FROM customers c
// JOIN (
// SELECT customer_id, SUM(amount) AS total_spent
// FROM transactions
// GROUP BY customer_id
// ) AS sub ON c.id = sub.customer_id
// WHERE sub.total_spent > 500;

$customers = new Select(
'customers',
['costumer.name', 'sub.total_spent'],
['customers.name', 'sub.total_spent'],
$this->pdo
);

$customers->join(
InnerJoin::ref(
new InnerQuery(
new Select(
(new Select(
'transactions',
['customer_id', 'SUM(amount) AS total_spent'],
$this->pdo
),
))
->groupBy('customer_id'),
'sub'
),
'id',
'customer_id'
)
);
$customers->compare('total_spent', '>', 500);

ok($customers->__toString())->out();

$customers = $customers->get();

$this->assertCount(2, $customers);
$this->assertCount(3, $customers);
}
}

0 comments on commit faeab8a

Please sign in to comment.