diff --git a/lib/Doctrine/DBAL/Query/QueryBuilder.php b/lib/Doctrine/DBAL/Query/QueryBuilder.php index 12584d960ab..bbbc9dae882 100644 --- a/lib/Doctrine/DBAL/Query/QueryBuilder.php +++ b/lib/Doctrine/DBAL/Query/QueryBuilder.php @@ -125,6 +125,13 @@ class QueryBuilder */ private $boundCounter = 0; + /** + * Whether or not to include a distinct flag in the SELECT clause + * + * @var bool + */ + private $isDistinct = false; + /** * Initializes a new QueryBuilder. * @@ -396,6 +403,29 @@ public function getMaxResults() return $this->maxResults; } + /** + * Sets the flag to only retrieve distinct results + * + * @param bool $isDistinct Set true to add the distinct flag, set to false to remove it + * + * @return $this This QueryBuilder instance. + */ + public function distinct($isDistinct = true) + { + $this->state = self::STATE_DIRTY; + $this->isDistinct = $isDistinct; + + return $this; + } + + /** + * Returns whether or not the query object is set to return only distinct results + */ + public function isDistinct() : bool + { + return $this->isDistinct; + } + /** * Either appends to or replaces a single, generic query part. * @@ -1099,7 +1129,7 @@ public function resetQueryPart($queryPartName) */ private function getSQLForSelect() { - $query = 'SELECT ' . implode(', ', $this->sqlParts['select']); + $query = 'SELECT' . ($this->isDistinct ? ' DISTINCT ' : ' ') . implode(', ', $this->sqlParts['select']); $query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '') . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') diff --git a/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php b/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php index fdd28d87847..c7060a96f63 100644 --- a/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php +++ b/tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php @@ -62,6 +62,17 @@ public function testSelectWithSimpleWhere() self::assertEquals('SELECT u.id FROM users u WHERE u.nickname = ?', (string) $qb); } + public function testSelectWithDistinct() + { + $qb = new QueryBuilder($this->conn); + + $qb->select('u.id') + ->from('users', 'u') + ->distinct(); + + self::assertEquals('SELECT DISTINCT u.id FROM users u', (string) $qb); + } + public function testSelectWithLeftJoin() { $qb = new QueryBuilder($this->conn); @@ -576,6 +587,25 @@ public function testSetFirstResult() self::assertEquals(10, $qb->getFirstResult()); } + public function testSetDistinct() + { + $qb = new QueryBuilder($this->conn); + $qb->distinct(); + + self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState()); + self::assertTrue($qb->isDistinct()); + } + + public function testSetDistinctFalse() + { + $qb = new QueryBuilder($this->conn); + $qb->distinct(true); + $qb->distinct(false); + + self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState()); + self::assertFalse($qb->isDistinct()); + } + public function testResetQueryPart() { $qb = new QueryBuilder($this->conn);