Unverified Commit 7241a651 authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #3696 from bingo-soft/master

Add support for DISTINCT clause
parents 81922a27 f90c2997
......@@ -87,6 +87,21 @@ and ``delete($tableName)``:
You can convert a query builder to its SQL string representation
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
~~~~~~~~~~~~
......
......@@ -52,22 +52,28 @@ class QueryBuilder
*/
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.
*
* @var mixed[]
*/
private $sqlParts = [
'select' => [],
'from' => [],
'join' => [],
'set' => [],
'where' => null,
'groupBy' => [],
'having' => null,
'orderBy' => [],
'values' => [],
];
private $sqlParts = self::SQL_PARTS_DEFAULTS;
/**
* The complete SQL string for this query.
......@@ -469,6 +475,25 @@ class QueryBuilder
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.
*
......@@ -1083,8 +1108,7 @@ class QueryBuilder
*/
public function resetQueryPart($queryPartName)
{
$this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName])
? [] : null;
$this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName];
$this->state = self::STATE_DIRTY;
......@@ -1098,7 +1122,8 @@ class QueryBuilder
*/
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()) : '')
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
......
......@@ -50,6 +50,17 @@ class QueryBuilderTest extends DbalTestCase
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
{
$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