尝试使用Zend\Db\Sql\Select
获取嵌套选择,但在文档或Google上根本看不到任何内容。
想要做这样的事情:
SELECT
table1.*,
(SELECT x,y,z FROM table2 WHERE table2.a = table1.a) as b
FROM table1
没有嵌套选择,它看起来像这样:
$select = new Zend\Db\Sql\Select;
$select
->columns(array(
'*'
))
->from('table1')
ZF1考虑创建一个subSelect项目,然后将其作为一个表达式添加到列表列表中,但在ZF2中它抱怨表达式需要是一个字符串。
编辑:嵌套选择需要作为一列,因为当在同一列名上使用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
答案 0 :(得分: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'
);
基本上,您可以使用一个select作为另一个select的谓词的值。
答案 1 :(得分: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
我没有运行此查询,但我确信它应该可以运行并为您提供所需的结果。希望我不会误解你的情况。以下是Zend Framework 2的等效选择。
$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)")
)
);
答案 2 :(得分:0)
我希望我能正确地解决你的问题......
仍然没有将自己升级到ZF2,但如果您使用的是MVC架构,那么这是您在ZF1中创建嵌套Select语句的方法之一(也可以在ZF2中尝试)。
$table1 = new table1();
$table1->select()->from('table1',array('*',
'b' => '(SELECT x,y,z FROM table2 WHERE table2.a = table1.a)',
));
更新:
在你的评论之后回到这一点,并意识到我写的代码不起作用,因为你将无法从另一个表中选择多个列到一个列(即b中的x,y,z)。 / p>
但是,如果你必须执行一些攻击,它会起作用。在另一个表上的函数,它给出一个列。 e.g。
$table1 = new table1();
$table1->select()->from('table1',array('*',
'b' => '(count (*) FROM table2 WHERE table2.a = table1.a)',
));
所以这会奏效。 通过这种方式,您可以获得一些在其上执行某些功能的列。 而另一个表(table2)中的其余列可以使用连接。
答案 3 :(得分:0)
您所描述的内容定义为JOIN。有一些不同的连接方案,我不会涵盖它们的差异,但最常见的是INNER JOIN或LEFT JOIN。
这确实可以在ZF2-Documentation of Zend\Db\Sql#Join
中找到查询看起来像这样:
Select
t1.*,
t2.field1,
t2.field2,
t2.field3
FROM
tablename1 t1,
tablename2 t2
WHERE
t1.field = t2.field
查看ZF2-Documentation of Zend\Db\Sql#Join的文档,我认为,Select会如下所示:
$select = new \Zend\Db\Sql\Select();
$select->columns(array(
'id',
'title',
// List ALL Columns from TABLE 1 - * is bad/slow!
), true)->from(array(
't1' => 'tablename1'
))->join(
'tablename2',
'id = t1.id',
array(
'username',
'email',
// List ALL Columns from TABLE 2 u want to select
),
$select::JOIN_INNER
)
另一个我认为:如果你不使用columns()
你SELECT *
但是为了你自己,开始写好的查询;)有更多的控制权你的代码!
不能保证这段代码有效,因为我自己不使用Zend \ Db,但是使用右侧的文档可以让你继续运行。