ZF - 使用CASE WHEN的MySQL SUM查询

时间:2016-03-19 04:15:56

标签: mysql sql zend-framework prepared-statement

尝试在zend框架1中编写以下查询:

SELECT
    SUM(CASE WHEN column2 = 'value1' THEN column3 END) AS 'mySpecialSum',
FROM `my_table` 
WHERE column4='value2' AND column5='value3'

测试我是这样写的:

$select = $this->select()
    ->from('my_table', array(
        'mySpecialSum'=>'SUM(CASE WHEN column2 = "value1" THEN column3 END)'
    ))
    ->where('column4=?', $value2)
    ->where('column5=?', $value3);
$data = $this->fetchAll($select);

有效 - 但我需要知道如何将value1包含为变量 - 例如$value1 - 最好使用占位符,以便语句准备好' - 尽量减少SQL注入的可能性。

目前尝试两种选择(不起作用):

$select = $this->select()
    ->from('my_table', array(
        'mySpecialSum'=>'SUM(CASE WHEN column2 = "{$value1}" THEN column3 END)'
    ))
    ->where('column4=?', $value2)
    ->where('column5=?', $value3);
$data = $this->fetchAll($select);

OR

$select = $this->select()
    ->from('my_table', array(
        'mySpecialSum'=>'SUM(CASE WHEN column2 = "{$this->_db->quote($value1)}" THEN column3 END)'
    ))
    ->where('column4=?', $value2)
    ->where('column5=?', $value3);
$data = $this->fetchAll($select);

1 个答案:

答案 0 :(得分:1)

在对预先准备好的陈述进行一些研究here之后,最好的方法似乎是:

$sql = 'SELECT SUM(CASE WHEN column2 = ? THEN column3 END) AS "mySpecialSum",
FROM my_table
WHERE content_type = ?
AND content_id = ?';

$preparedStatement = $this->getAdapter()->query($sql, array($value1, $value2, $value3));
$data = $preparedStatement->fetchAll();

工作的两个选项 - 但两者都感觉像黑客(并且顺便提一下,比上面的'预备语句'方法稍慢) - 是:

$select = $this->select()
    ->from('my_table', array(
        'mySpecialSum'=>'SUM(CASE WHEN column2 = "' . $value1 . '" THEN column3 END)'
    ))
    ->where('column4=?', $value2)
    ->where('column5=?', $value3);
$data = $this->fetchAll($select);

$start = microtime();

$select = $this->select()
    ->from('my_table', array(
        'mySpecialSum'=>'SUM(CASE WHEN column2 = ' . $this->_db->quote($value1) . ' THEN column3 END)'
    ))
    ->where('column4=?', $value2)
    ->where('column5=?', $value3);
$data = $this->fetchAll($select);

$end = microtime();
$timeTaken = $end - $start;

microtime()之前&之后进行速度测试以比较两种方法:
...显示使用zf $this->_db->quote()或不是

的差异可以忽略不计

然而,奇怪的是,使用$this->getAdapter()->select()而不是简单地使用$this->select()时,速度提高了5倍:

$select = $this->getAdapter()
    ->select()
    ->from('my_table', array(
        'mySpecialSum'=>'SUM(CASE WHEN column2 = ' . $this->_db->quote($value1) . ' THEN column3 END)'
    ))
    ->where('column4=?', $value2)
    ->where('column5=?', $value3);
$data = $this->getAdapter()->fetchAll($select);