2014-09-12 41 views
0

我有一個簡單的SQL查詢,我想通過Yii 1.15 ORM運行。通過使用YII CDbCriteria或find()方法執行此SQL的更好方法?

SQL語法

SELECT (sum(last_question) - count(last_question)) as data 
FROM tbl_game 
WHERE last_question <> 0 

我的問題是

  1. 什麼是更好的Yii辦法做到這一點?

  2. 如果使用Yii,還有可能得到整數值的返回而不是CModel Object

更新1:

我已經嘗試過這樣的事情。它永遠不會返回question_answered。我不知道它爲什麼這樣做。如果CDbCriteria有這樣的選項select那麼它應該工作。

$criteria = new CDbCriteria; 
    $criteria->select = '(sum(`last_question`) - count(`last_question`)) as "question_answered" '; 
    $criteria->condition = "last_question <> 0"; 
    return game::model()->find($criteria); 

更新2:

這是返回模型的上述標準的原始輸出。這裏沒有question_answered

我確信表中有記錄。

而且我已經更換了「與」的建議,它仍然不放棄question_answered

object(game)[103] 
public 'points' => null 
private '_new' (CActiveRecord) => boolean false 
private '_attributes' (CActiveRecord) => 
    array (size=0) 
    empty 
private '_related' (CActiveRecord) => 
    array (size=0) 
    empty 
private '_c' (CActiveRecord) => null 
private '_pk' (CActiveRecord) => null 
private '_alias' (CActiveRecord) => string 't' (length=1) 
private '_errors' (CModel) => 
    array (size=0) 
    empty 
private '_validators' (CModel) => null 
private '_scenario' (CModel) => string 'update' (length=6) 
private '_e' (CComponent) => null 
private '_m' (CComponent) => null 
+0

它永遠不會給你一些'question_answered'。你正在做一個'Model-> find()',它總是返回一個活動記錄或null。由於Yii不知道如何將結果映射到模型,因此無法將複雜選擇填充到此模型中並返回模型。 'Find'更像是一個記錄過濾器。你在這裏選擇的是什麼?你想要接收什麼? – 2014-09-12 13:48:31

+0

'question_answered'來自第一個SQL查詢。我知道它不可能得到int,我會得到CModel。但是爲什麼我不能用CDbCriteria執行這個事情 – Sushant 2014-09-12 13:55:21

+0

因爲你得到(並且想要?)一個整數,但是'Model-> find()'將返回一個活動的記錄模型或null。用find()來做這件事是沒有意義的。什麼是這個整數?模型的ID還是隻是一些東西的計數?如果它不涉及模型(如ID),那麼通過find()獲取它就沒有意義。 – 2014-09-12 14:01:36

回答

1

我想我有一個解決方案給你。 你有的主要問題是,你想選擇一個模型中不存在的字段('question_answered')。所以你需要做的是將這個字段添加到模型中。

型號:

class Game extends CActiveRecord { 
    ... 
    public $question_answered; 
    ... 
} 

然後,你可以做某事像這樣:

$criteria = new CDbCriteria; 
    $criteria->select = '(sum(`last_question`)-count(`last_question`)) as question_answered'; 
    $criteria->condition = "last_question <> 0"; 
    echo Game::model()->find($criteria)->question_answered; 

每次的select子句中添加不存在的領域,你必須在添加該字段模型。

希望這有幫助,它適用於我。

+0

你想如何避免它? – Asped 2014-09-14 16:17:16

+0

我將使用一些其他現有的屬性,如'id'來獲取臨時結果。因爲它將主要是標量提取查詢,所以它不會傷害:) – Sushant 2014-09-14 16:32:31

0

您可以使用Query Builder

Yii::app()->db->createCommand() 
    ->select('SUM(`last_question`) - COUNT(`last_question`)') // if using "()", than you have to escape columns names manualy. 
    ->from('tbl_game') 
    ->where('last_question != :param', [':param' => 0]) 
    ->queryScalar(); 

隨着CDbCriteria,嘗試這樣的事情(未經測試):

$c = new CDbCriteria(); 
$c->select = 'SUM(`last_question`) - COUNT(`last_question`) AS "result"'; 
$c->addCondition('last_question != :param'); 
$c->params = [':param' => 0]; 

Game::model()->find($c)->result; 
+0

是否可以通過find或CDbCriteria來完成,我的主要焦點是使用find方法選擇列。可能嗎? – Sushant 2014-09-12 11:32:10

+0

是的,但我已經嘗試過了。看到更新的問題。它永遠不會返回「結果」 – Sushant 2014-09-12 11:46:26

+0

@sushant因爲你正在返回完整模型,只返回'return game :: model() - > find($ criteria) - > question_answered;' – Justinas 2014-09-12 12:00:05

0

要直接,並沒有得到值,你可以使用DAO/PDO的模型:

$sql = 'SELECT SUM(`last_question`) - COUNT(`last_question`) AS data 
FROM tbl_game 
WHERE last_question <> :param'; 
$connection = Yii::app()->db; 
$command = $connection->createCommand($sql); 
$value = $command->queryScalar(array(':param' => 0)); 

$value然後找到的第一個記錄。 如果你想要多個記錄,你可以做一個$values = $command->queryAll(true, array(':param' => 0))它返回一個數組。

More info here.

+0

我的觀點是使用CDBcriteria或find方法來執行它。是否有可能? – Sushant 2014-09-12 11:51:57

+0

我在引用你的第二個問題'Get an int an not a model '你可以像上面寫的那樣用CDbCriteria來做,只需從你的選擇中取出雙引號就可以了。我有點ID?如果是這樣,你將不得不用'findByPk'來檢索模型。 – 2014-09-12 12:07:37

0

還有一個更整潔的選項,您可以使用,我這不能確定是否適用於你的情況。如果你有一些模型,該模型涉及模型last_question屬性和關係HAS_MANYMANY_MANY你可以在你的第一個模型,比調用任何其他關係定義STAT關係。

public function relations() 
{ 
    return array(
     'someVariableName'=>array(self::STAT, 'ModelNameWhichYouRelateto', 'foreignkey_attr', array(
      'select'=>'SUM(last_question) - COUNT(last_question)', 
      'condition'=>'last_question <> 0' 
     )), 
    ); 
} 

可以再用

$model->someVariableName 

只需調用它,並得到一個整數。

+0

'last_question'在同一個表中,所以我不能使用關係 – Sushant 2014-09-12 13:12:25