使用YII CDbWriter或find()方法执行此SQL的更好方法


Better way to do this SQL by using YII CDbCriteria or find() methods?

我有一个简单的SQL查询,我想通过Yii 1.15 ORM运行它。

SQL语法

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

我的问题是

  1. Yii有什么更好的方法呢?

  2. 如果使用Yii,是否可以获得整数值而不是CModel对象的返回?

更新1:

我已经试过这样的东西了。它永远不会返回question_answered。我不知道它为什么这么做。如果CDbCriteriaselect这样的选项,那么它应该可以工作。

    $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

我想我有一个解决方案。您面临的主要问题是,您想要选择模型中不存在的字段("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子句中添加不存在的字段时,都必须在模型中添加此字段。

希望这对我有帮助,它对我有用。

要直接获得值,而不是作为模型,可以使用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));

CCD_ 8则是找到的第一个记录。如果你想要多条记录,你可以做一个$values = $command->queryAll(true, array(':param' => 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

并得到一个整数。

您可以使用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();

使用CDbWriter,尝试这样的东西(未测试):

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