我正在试图弄清楚如何使用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');
答案 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响应。