Commit 5829020e by Qiang Xue

Fixes #5223: Query builder now supports selecting sub-queries as columns

parent 48ec791e
......@@ -85,6 +85,15 @@ When specifying columns, you may include the table prefixes or column aliases, e
If you are using array to specify the columns, you may also use the array keys to specify the column aliases,
e.g., `['user_id' => 'user.id', 'user_name' => 'user.name']`.
Starting from version 2.0.1, you may also select sub-queries as columns. For example,
```php
$subQuery = (new Query)->select('COUNT(*)')->from('user');
$query = (new Query)->select(['id', 'count' => $subQuery])->from('post');
// $query represents the following SQL:
// SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post`
```
To select distinct rows, you may call `distinct()`, like the following:
```php
......
......@@ -5,6 +5,7 @@ Yii Framework 2 sphinx extension Change Log
-----------------------
- Bug #5601: Simple conditions in Query::where() and ActiveQuery::where() did not allow `yii\db\Expression` to be used as the value (cebe, stevekr)
- Enh #5223: Query builder now supports selecting sub-queries as columns (qiangxue)
2.0.0 October 12, 2014
......
......@@ -446,6 +446,9 @@ class QueryBuilder extends Object
if ($column instanceof Expression) {
$columns[$i] = $column->expression;
$params = array_merge($params, $column->params);
} elseif ($column instanceof Query) {
list($sql, $params) = $this->build($column, $params);
$columns[$i] = "($sql) AS " . $this->db->quoteColumnName($i);
} elseif (is_string($i)) {
if (strpos($column, '(') === false) {
$column = $this->db->quoteColumnName($column);
......
......@@ -8,13 +8,13 @@ Yii Framework 2 Change Log
- Bug #5584: `yii\rbac\DbRbacManager` should not delete items when deleting a rule on a database not supporting cascade update (mdmunir)
- Bug #5601: Simple conditions in Query::where() and ActiveQuery::where() did not allow `yii\db\Expression` to be used as the value (cebe, stevekr)
- Bug: Gii console command help information does not contain global options (qiangxue)
- Enh #5223: Query builder now supports selecting sub-queries as columns (qiangxue)
- Enh #5587: `json_encode` is now used with `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE` where it makes sense, also
it is now default for `Json::encode()` (samdark)
- Enh #5600: Allow configuring debug panels in `yii\debug\Module::panels` as panel class name strings (qiangxue)
- Enh #5613: Added `--overwrite` option to Gii console command to support overwriting all files (motin, qiangxue)
- Enh #5646: Call `yii\base\ErrorHandler::unregister()` instead of `restore_*_handlers` directly (aivus)
2.0.0 October 12, 2014
----------------------
......
......@@ -626,6 +626,9 @@ class QueryBuilder extends \yii\base\Object
if ($column instanceof Expression) {
$columns[$i] = $column->expression;
$params = array_merge($params, $column->params);
} elseif ($column instanceof Query) {
list($sql, $params) = $this->build($column, $params);
$columns[$i] = "($sql) AS " . $this->db->quoteColumnName($i);
} elseif (is_string($i)) {
if (strpos($column, '(') === false) {
$column = $this->db->quoteColumnName($column);
......
......@@ -422,4 +422,20 @@ class QueryBuilderTest extends DatabaseTestCase
list($actualQuerySql, $queryParams) = $this->getQueryBuilder()->build($query);
$this->assertEquals($expectedQuerySql, $actualQuerySql);
}
public function testSelectSubquery()
{
$subquery = (new Query())
->select('COUNT(*)')
->from('operations')
->where('account_id = accounts.id');
$query = (new Query())
->select('*')
->from('accounts')
->addSelect(['operations_count' => $subquery]);
list ($sql, $params) = $this->getQueryBuilder()->build($query);
$expected = 'SELECT *, (SELECT COUNT(*) FROM `operations` WHERE account_id = accounts.id) AS `operations_count` FROM `accounts`';
$this->assertEquals($expected, $sql);
$this->assertEmpty($params);
}
}
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