Yii CDbCriteria查询匹配一个表中的多个行

时间:2012-06-19 21:44:37

标签: mysql yii

我正在试图弄清楚如何使用Yii的CDbCriteria构建查询,该查询等同于以下内容:

 SELECT 
        * 
FROM 
        user u 
JOIN ( 
        SELECT * 
        FROM skill_assessment s 
        WHERE s.skill = 'HTML' 
        AND s.score >= 80 
) b ON 
        (u.id = b.userId) 
JOIN ( 
        SELECT * 
        FROM skill_assessment s 
        WHERE s.skill = 'CSS3' 
        AND s.score >= 80
) c ON 
        (u.id = c.userId);
etc...

这是我到目前为止所做的,但是无效:

$criteria = new CDbCriteria();
$criteria->alias = "u";
$criteria->select = "*";
$criteria->join = "JOIN skill_assessment s ON (u.id=s.userId)";
for($i = 0; $i < count($skill_filters); $i++) {
    $criteria->addCondition("s.skill='".$skill_filters[$i]->skill."' AND s.score >= ".$skill_filters[$i]->level);
}

$users = UserModel::model()->findAll($criteria);

非常感谢任何帮助。 提前谢谢。

编辑: 我能够将sql查询构建为字符串并使用findAllBySql,它返回了与我的搜索条件匹配的正确UserModel,问题是我无法让它返回相关的SkillAssessmentModels。他们不会使用初始查询返回,如下所示:

$users = UserModel::model()->with('skill_assessments')->findAllBySql($sql);

我也不会得到这样的结果:

$users = UserModel::model->findAllBySql($sql);
foreach($users as $user)
{
     $user->skill_assessments = $user->getRelated('skill_assessments');
}

关于如何获得相关模型的任何想法? 奇怪的是,在我的应用程序的其他地方,如果我这样做,我可以得到相关的模型:

$user = UserModel::model->findByPk($id);
$user->skill_assessments->getRelated('skill_assessments');

3 个答案:

答案 0 :(得分:2)

addCondition的第二个参数默认为'AND'。这是你想要的?可能是您应为'OR'定义$operator并在条件周围添加大括号。 但在您的情况下,addCondition将应用于用户表,而不是 JOIN

我认为这应该适合你:

$criteria = new CDbCriteria();
$criteria->alias = "u";
$criteria->together= "skill_assessment";
$where = array();

for($i = 0; $i < count($skill_filters); $i++) {
    $where[] = "(s.skill='".$skill_filters[$i]->skill."' AND s.score >= ".$skill_filters[$i]->level . ')';
}
$criteria->join = 'JOIN skill_assessment s ON (u.id=s.userId' . ( $where ? ( ' AND (' . join( ' OR ', $where ) . ')' ) : '') . ')';

$users = UserModel::model()->findAll($criteria);

像这样获取_skill_assessment_:

foreach( $users->skill_assessment as $skill_assessment )
{
    echo $skill_assessment->userId;
}

答案 1 :(得分:1)

在这个级别保持简单:

$sql="select * from mytable where id = :id";
$cmd = Yii::app()->db->createCommand($sql)->bindParam("id", $res_id);
$cmd->execute();

答案 2 :(得分:0)

非常感谢Boris Belenski! 你所建议的不是相当我需要什么,但它确实让我得到了我需要的东西。以下是我最终得到的结论:

$str = "abcdefghijklmnopqrstuvwxyz";
            $idxs = str_split($str);

            $criteria = new CDbCriteria();
            $criteria->alias = "u";
            $joins = array();
            for($i = 0; $i < count($skill_filters); $i++)
            {
                $joins[] = " JOIN (SELECT * FROM skill_assessment s WHERE s.skill = '" . $skill_filters[$i]->skill ."' AND s.score >= " . $skill_filters[$i]->level . ") " . $idxs[$i] . " ON (u.id = " . $idxs[$i] . ".userId) ";
            }

            $criteria->join = join(' ', $joins);
            $users = UserModel::model()->findAll($criteria);
            foreach($users as $user)
            {
                $user->skill_assessments = $user->getRelated('skill_assessments');
            }

真正关键的部分是$ join数组。 这将允许您在skill_assessments表中获得符合所有行匹配条件的所有用户。

另外,我可能会懒散地在普通视图中加载View中的技能评估,但我现在需要为每个用户获取所有skill_assessments,以便将它们传回给用户的ajax响应。