2016-03-19 48 views
0

試圖寫在Zend框架1以下查詢:ZF - MySQL的SUM查詢使用CASE WHEN

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

預處理語句上一些研究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()或不是

可以忽略不計的差異然而,奇怪的是有5倍使用$this->getAdapter()->select()而不是簡單地使用時速度增加$this->select()

$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);