Zend_DB subselect / subquery怎么样?

时间:2013-05-08 13:31:42

标签: zend-framework zend-db subquery

我有这个原始的sql语句,我试图通过Zend_DB执行。

$sql = 'SELECT relocationaction.id, relocationaction.vehicle, relocationaction.start,         relocationaction.end, relocationaction.return ' .
            'FROM relocationaction,
              (SELECT vehicle, MAX(end) AS maxend
              FROM relocationaction
              GROUP BY vehicle) AS co2
            WHERE co2.vehicle = relocationaction.vehicle
            AND(relocationaction.monitor = 1)
            AND (relocationaction.return IS NULL)
            AND (start <= ?)
            AND relocationaction.end = co2.maxend';

我找到了一种使用这种表示法的可能解决方案,但它被渲染成一个完全不同的错误的sql语句,带有连接和奇怪的表名。

$tbl    = $this->getDbTable();
$select = $tbl->select()->setIntegrityCheck(false);

$subSelect = $select->from('relocationaction', array('vehicle', 'maxend' => 'MAX(relocationaction.end)'))
                    ->group('vehicle');
$subSelectString = '(' . $subSelect->__toString() . ')';

$select ->from(
                array('relocationaction'), array('id', 'date' => 'start', 'enddate' => 'end', 'return'),
                array('co2' => $subSelectString)
            )
        ->joinLeft('exhibitvehicle', 'exhibitvehicle.id = relocationaction.vehicle', array())
        ->where('co2.vehicle = relocationaction.vehicle')
        ->where('relocationaction.monitor = 1')
        ->where('relocationaction.return IS NULL')
        ->where('start <= ?', $start->get('yyyy-MM-dd'))
        ->where('relocationaction.end = co2.maxend');

任何人都可以给我一个提示吗?

由于 杰西

更新

这是第二个表达式(总垃圾)的结果

SELECT `relocationaction`.`vehicle`, 
    MAX(relocationaction.end) AS `maxend`, 
    `relocationaction_2`.`id`, 
    `relocationaction_2`.`start` AS `date`, 
    `relocationaction_2`.`end` AS `enddate`, 
    `relocationaction_2`.`return` 
FROM `relocationaction`
INNER JOIN `(
    SELECT ``relocationaction``.``vehicle``,
    MAX(relocationaction.end) AS ``maxend`` FROM ``relocationaction`` GROUP BY ``vehicle``)`.`relocationaction` AS `relocationaction_2`
LEFT JOIN `exhibitvehicle` ON exhibitvehicle.id = relocationaction.vehicle 
WHERE (col2.vehicle = relocationaction.vehicle) 
AND (relocationaction.monitor = 1) 
AND (relocationaction.return IS NULL) 
AND (start <= '2013-05-08') 
AND (relocationaction.end = col2.maxend) 
GROUP BY `vehicle`

2 个答案:

答案 0 :(得分:1)

如果你在from()中使用string,Zend_Db_Select会认为它是一个表名,所以它会逃脱它。

解决方案是将您的子选择包装到Zend_Db_Expr。

$tbl    = $this->getDbTable();
$select = $tbl->select()->setIntegrityCheck(false);

$subSelect = $select->from('relocationaction', array('vehicle', 'maxend' => 'MAX(relocationaction.end)'))
                ->group('vehicle');
$subSelectString = '(' . $subSelect->__toString() . ')';

$select ->from(
            array('relocationaction'), array('id', 'date' => 'start', 'enddate' => 'end', 'return'),
            array('co2' => new Zend_Db_Expr($subSelectString))
        )
    ->joinLeft('exhibitvehicle', 'exhibitvehicle.id = relocationaction.vehicle',     array())
    ->where('co2.vehicle = relocationaction.vehicle')
    ->where('relocationaction.monitor = 1')
    ->where('relocationaction.return IS NULL')
    ->where('start <= ?', $start->get('yyyy-MM-dd'))
    ->where('relocationaction.end = co2.maxend');

答案 1 :(得分:0)

好的,我们走了。我努力寻找Zend_Db_Table的解决方案,但失败了很多时间。这就是我最终用PDO做到的原因,正如@ user466764所建议的那样。谢谢你的帮助。

$tbl    = $this->getDbTable();
    $query = 'SELECT relocationaction.id,
                        relocationaction.vehicle,
                        relocationaction.start,
                        relocationaction.end,
                        relocationaction.return
            FROM relocationaction
              (SELECT vehicle, MAX(end) AS maxend
              FROM relocationaction
              GROUP BY vehicle) AS co2
            WHERE co2.vehicle = relocationaction.vehicle
            AND(relocationaction.monitor = 1)
            AND (relocationaction.return IS NULL)
            AND (start <= "' . $start->get('yyyy-MM-dd') . '")
            AND relocationaction.end = co2.maxend';

    $sth = $tbl->getAdapter()->prepare($query);
    $sth->execute();
    $entries = $sth->fetchAll();