Commit f90c2997 authored by Bingo-Soft's avatar Bingo-Soft

Add support for DISTINCT clause

parent 81922a27
...@@ -87,6 +87,21 @@ and ``delete($tableName)``: ...@@ -87,6 +87,21 @@ and ``delete($tableName)``:
You can convert a query builder to its SQL string representation You can convert a query builder to its SQL string representation
by calling ``$queryBuilder->getSQL()`` or casting the object to string. by calling ``$queryBuilder->getSQL()`` or casting the object to string.
DISTINCT-Clause
~~~~~~~~~~~~~~~
The ``SELECT`` statement can be specified with a ``DISTINCT`` clause:
.. code-block:: php
<?php
$queryBuilder
->select('name')
->distinct()
->from('users')
;
WHERE-Clause WHERE-Clause
~~~~~~~~~~~~ ~~~~~~~~~~~~
......
...@@ -52,22 +52,28 @@ class QueryBuilder ...@@ -52,22 +52,28 @@ class QueryBuilder
*/ */
private $connection; private $connection;
/*
* The default values of SQL parts collection
*/
private const SQL_PARTS_DEFAULTS = [
'select' => [],
'distinct' => false,
'from' => [],
'join' => [],
'set' => [],
'where' => null,
'groupBy' => [],
'having' => null,
'orderBy' => [],
'values' => [],
];
/** /**
* The array of SQL parts collected. * The array of SQL parts collected.
* *
* @var mixed[] * @var mixed[]
*/ */
private $sqlParts = [ private $sqlParts = self::SQL_PARTS_DEFAULTS;
'select' => [],
'from' => [],
'join' => [],
'set' => [],
'where' => null,
'groupBy' => [],
'having' => null,
'orderBy' => [],
'values' => [],
];
/** /**
* The complete SQL string for this query. * The complete SQL string for this query.
...@@ -469,6 +475,25 @@ class QueryBuilder ...@@ -469,6 +475,25 @@ class QueryBuilder
return $this->add('select', $selects); return $this->add('select', $selects);
} }
/**
* Adds DISTINCT to the query.
*
* <code>
* $qb = $conn->createQueryBuilder()
* ->select('u.id')
* ->distinct()
* ->from('users', 'u')
* </code>
*
* @return $this This QueryBuilder instance.
*/
public function distinct() : self
{
$this->sqlParts['distinct'] = true;
return $this;
}
/** /**
* Adds an item that is to be returned in the query result. * Adds an item that is to be returned in the query result.
* *
...@@ -1083,8 +1108,7 @@ class QueryBuilder ...@@ -1083,8 +1108,7 @@ class QueryBuilder
*/ */
public function resetQueryPart($queryPartName) public function resetQueryPart($queryPartName)
{ {
$this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName]) $this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName];
? [] : null;
$this->state = self::STATE_DIRTY; $this->state = self::STATE_DIRTY;
...@@ -1098,7 +1122,8 @@ class QueryBuilder ...@@ -1098,7 +1122,8 @@ class QueryBuilder
*/ */
private function getSQLForSelect() private function getSQLForSelect()
{ {
$query = 'SELECT ' . implode(', ', $this->sqlParts['select']); $query = 'SELECT ' . ($this->sqlParts['distinct'] ? 'DISTINCT ' : '') .
implode(', ', $this->sqlParts['select']);
$query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '') $query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '')
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
......
...@@ -50,6 +50,17 @@ class QueryBuilderTest extends DbalTestCase ...@@ -50,6 +50,17 @@ class QueryBuilderTest extends DbalTestCase
self::assertEquals('SELECT u.id FROM users u', (string) $qb); self::assertEquals('SELECT u.id FROM users u', (string) $qb);
} }
public function testSimpleSelectWithDistinct() : void
{
$qb = new QueryBuilder($this->conn);
$qb->select('u.id')
->distinct()
->from('users', 'u');
self::assertEquals('SELECT DISTINCT u.id FROM users u', (string) $qb);
}
public function testSelectWithSimpleWhere() : void public function testSelectWithSimpleWhere() : void
{ {
$qb = new QueryBuilder($this->conn); $qb = new QueryBuilder($this->conn);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment