簡體   English   中英

嵌套使用ZF2選擇

[英]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#JoinZF2文檔中找到

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM