嵌套使用ZF2选择

Int*_*lix 6 zend-framework2

尝试使用嵌套选择Zend\Db\Sql\Select,在文档或谷歌上看不到任何内容.

想要做这样的事情:

SELECT 
    table1.*,
    (SELECT x,y,z FROM table2 WHERE table2.a = table1.a) as b
FROM table1 
Run Code Online (Sandbox Code Playgroud)

没有嵌套选择,它看起来像这样:

$select = new Zend\Db\Sql\Select;
$select
 ->columns(array(
    '*'
 ))
 ->from('table1')
Run Code Online (Sandbox Code Playgroud)

ZF1着眼于创建一个subSelect项目,然后将其作为一个Expression添加到列列表中,但在ZF2中它抱怨一个Expression需要是一个字符串.

编辑:嵌套选择需要作为一列,因为当在同一列名上使用GROUP BY时,我最终会得到相乘的行.这是我想要进入的正确查询Zend\Db\Sql\Select:

SELECT
    users.id, 
    (SELECT count(explorations.id) FROM explorations WHERE user_id = users.id) as total_explorations, 
    count(villages.id)
FROM 
    users
INNER JOIN
    villages
        on (villages.user_id = users.id)
GROUP BY 
    users.id
Run Code Online (Sandbox Code Playgroud)

wei*_*ney 6

Ralph Schindler拥有一个他在Zend\Db中专门实现的不同数据库模式的存储库.这是一个子选择:https://github.com/ralphschindler/Zend_Db-Examples/blob/master/example-20.php

内容如下:

<?php

/** @var $adapter Zend\Db\Adapter\Adapter */
$adapter = include ((file_exists('bootstrap.php')) ? 'bootstrap.php' : 'bootstrap.dist.php');
refresh_data($adapter);

use Zend\Db\Sql;
use Zend\Db\ResultSet\ResultSet;

$sql = new Sql\Sql($adapter);

$subselect = $sql->select();
$subselect->from('artist')
    ->columns(array('name'))
    ->join('album', 'artist.id = album.artist_id', array())
    ->where->greaterThan('release_date', '2005-01-01');


$select = $sql->select();
$select->from('artist')
    ->order(array('name' => Sql\Select::ORDER_ASCENDING))
    ->where
        ->like('name', 'L%')
        ->AND->in('name', $subselect);

$statement = $sql->prepareStatementForSqlObject($select);

$result = $statement->execute();

$rows = array_values(iterator_to_array($result));

assert_example_works(
    count($rows) == 2
    && $rows[0]['name'] == 'Lady Gaga'
    && $rows[1]['name'] == 'Linkin Park'
);
Run Code Online (Sandbox Code Playgroud)

基本上,您可以使用一个select作为另一个select的谓词的值.


xan*_*ong 4

我建议你重构你的 SQL 查询。我不确定您使用的是哪个数据库,但是如果您使用 MySQL,则 COUNT 函数可以使用 DISTINCT 关键字。这样就不会计算重复的 id。我已将您的 SQL 查询调整为我将使用的查询,这样您就无需进行内部选择。

SELECT
    users.id,
    COUNT(DISTINCT explorations.id) AS total_explorations,
    COUNT(DISTINCT villages.id) AS total_villages
FROM users
    INNER JOIN villages ON villages.user_id = users.id
    INNER JOIN explorations ON explorations.user_id = users.id
GROUP BY users.id
Run Code Online (Sandbox Code Playgroud)

我还没有运行这个查询,但我确信它应该可以工作并为您提供您想要的结果。希望我没有误解你的情况。下面是等效的 Zend Framework 2 select。

$select = $sql->select('users');
$select->columns(array('id'));
$select->join('villages', 
              'villages.user_id = users.id', 
               array(
                   'total_villages' => new Expression("COUNT(DISTINCT villages.id)")
               )
);
$select->join('explorations', 
              'explorations.user_id = users.id', 
               array(
                   'total_explorations' => new Expression("COUNT(DISTINCT explorations.id)")
               )
);
Run Code Online (Sandbox Code Playgroud)