[英]Nested Select with ZF2
嘗試使用Zend\\Db\\Sql\\Select
獲取嵌套選擇,並且在文檔或谷歌上看不到任何內容。
想要做這樣的事情:
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項目,然后將其作為一個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
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的謂詞的值。
我建議你重構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)")
)
);
我希望我能正確地解決你的問題......
仍然沒有將自己升級到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)。
但是,如果你必須執行一些攻擊,它會起作用。 在另一個表上的函數,它給出一個列。 例如
$table1 = new table1();
$table1->select()->from('table1',array('*',
'b' => '(count (*) FROM table2 WHERE table2.a = table1.a)',
));
所以這會奏效。 通過這種方式,您可以獲得一些在其上執行某些功能的列。 而另一個表(table2)中的其余列可以使用連接。
您所描述的內容被定義為JOIN 。 有一些不同的連接方案,我不會涵蓋它們的差異,但最常見的是INNER JOIN或LEFT JOIN。
這確實可以在Zend \\ Db \\ Sql#Join的ZF2文檔中找到
Query將如下所示:
Select
t1.*,
t2.field1,
t2.field2,
t2.field3
FROM
tablename1 t1,
tablename2 t2
WHERE
t1.field = t2.field
查看ZF2的文檔 - 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,但是使用右側的文檔可以讓你運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.