将此查询转换为yii CDbCriteria

时间:2014-07-03 14:17:52

标签: mysql yii

我对yii很新,还在努力弄清楚一些事情。如何使用CDbCriteria将此mysql查询更改为Yii的查询?

SELECT DISTINCT p.prefix, p.state
                     FROM `store` as d 
                     JOIN (`zip` as p)
                     ON (d.zip = p.zip)
                     WHERE d.store_code='".(int)$storeCode."'
                     GROUP BY p.prefix, p.state
                     ORDER BY p.state ASC

这是我到目前为止所做的事情

    $criteria = new CDbCriteria();
    $criteria->select = array('prefix','state');
    $criteria->join="zip";

    $criteria->condition = 'store_code=:store_code';
    $criteria->params = array(':store_code'=> (int)$storeCode);
    $criteria->order = 'state ASC';

    $query = AB::model()->findAll($criteria); //query

但它给了我这个错误

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'zip WHERE store_code=64 ORDER BY state ASC' at line 1. The SQL statement executed was: SELECT prefix, state FROM `store` `t` zip WHERE store_code=:store_code ORDER BY state ASC. Bound with :store_code=64 
当我使用下面的命令使用第一个查询时,

BONUS:。返回结果需要2.2秒。知道为什么这么慢?或者如何加快速度? (商店表有2518行,状态有20行)

$query = Yii::app()->db->createCommand($sql)->queryAll();

2 个答案:

答案 0 :(得分:1)

要回答您的直接问题,我认为加入语法已关闭。来自文档:

how to join with other tables. This refers to the JOIN clause in an SQL statement. For example, 'LEFT JOIN users ON users.id=authorID'.

因此,在我们的情况下,您的命令应该通过执行类似

的操作来运行
$criteria = new CDbCriteria();
$criteria->select = array('prefix','state');
$criteria->join="LEFT JOIN zip ON t.zip = zip.zip";

$criteria->condition = 'store_code=:store_code';
$criteria->params = array(':store_code'=> (int)$storeCode);
$criteria->order = 'state ASC';

$query = AB::model()->findAll($criteria); //query

t是Yii别名你的基表(无论AB代表什么。存储?)。

您还可以使用Yii查询构建器来完成此任务。例如

$data = Yii::app()->db->createCommand()
    ->selectDistinct(array("prefix","store"))
    ->from('store d')
    ->leftJoin('zip p', 'd.zip=p.zip')
    ->where('store_code=:store_code', array(':store_code'=>(int)$storeCode))
    ->queryAll();

但我强烈建议您更多地了解模特的关系。 Yii的活跃记录非常好。如果您建立了关系,那么您需要做的就是使用AB::models->findAllByAttributes(array("store_code"=>$myCode));找到所需的模型,然后执行$abModel->zip->column_name

你也可以做一些叫做'渴望加载'的事情。根据您计划查询关系的次数(在for循环中,或只是一次),您可能希望急于加载以提高性能。 E.g AB::model()->with("zip")->findAll($criteria); 您不必这样做,并且急于加载并不总是最佳做法。

如果您建立关系,您需要做的就像

$abModels = AB::models->with('zip')->findAllByAttributes(array("store_code"=>$myCode));
foreach ($abModels as $abModel) {
    $state = $abModel->zip->state;
    $prefix = $abModel->zip->prefix;
}

干杯

答案 1 :(得分:0)

试试这个:

$criteria = new CDbCriteria();
$criteria->alias = 'd';
$criteria->select = array('p.prefix','p.state');
$criteria->join='JOIN zip d ON d.zip = p.zip';
$criteria->condition = 'd.store_code=:store_code';
$criteria->params = array(':store_code'=> (int)$storeCode);
$criteria->group='p.prefix, p.state';
$criteria->order = 'p.state ASC';