一直用yii自带的关联查询,通过定义relation,然后在查询方法中通过with建立连接,但是今天发现一个问题,因为yii1自带的这种关联查询时采用左联接left jion,这在我这里出现了问题。
具体描述:表a模型中关联的表有b,c表,查询出来的总数是a表的全部数据条数,但是显示出来的实际记录数和条数不匹配。
我查了一下mysql左联接的定义:先将左表数据查出,然后根据on后面的条件,将右表中凡是id与左表id相等的记录都查出来,与匹配的左表记录依次排成一行或多行,若无匹配的记录,则显示null。
这样就可以看到,查询的条数和实际记录数是不匹配的。
===================================================================================================
在百度上找到一个解释的蛮详细的,现在贴出来看看
一般所说的左连接,外连接是指左外连接,右外连接。做个简单的测试你看吧。 先说左外连接和右外连接: [TEST1@orcl#16-12月-11] SQL>select * from t1; ID NAME ---------- -------------------- 1 aaa 2 bbb [TEST1@orcl#16-12月-11] SQL>select * from t2; ID AGE ---------- ---------- 1 20 3 30 左外连接: [TEST1@orcl#16-12月-11] SQL>select * from t1 left join t2 on t1.id=t2.id; ID NAME ID AGE ---------- -------------------- ---------- ---------- 1 aaa 1 20 2 bbb 右外连接: [TEST1@orcl#16-12月-11] SQL>select * from t1 right join t2 on t1.id=t2.id; ID NAME ID AGE ---------- -------------------- ---------- ---------- 1 aaa 1 20 3 30 从上面的显示你可以看出:左外连接是以左边的表为基准。通俗的讲,先将左边的表全部显示出来,然后右边的表id与左边表id相同的记录就“拼接”上去,比如说id为1的记录。如果没有匹配的id,比如说t1中id为2的t2中就没有。那边就以null显示。 右外连接过程正好相反。 再看内连接: [TEST1@orcl#16-12月-11] SQL>select * from t1 inner join t2 on t1.id=t2.id; ID NAME ID AGE ---------- -------------------- ---------- ---------- 1 aaa 1 20 看到没有? 只有一条记录。内连接就是只取出符合过滤条件的记录 也就是t1.id=t2.id 那么符合t1.id=t2.id的记录只有id=1这一条,所以只显示一条。 不像外连接,是将你作为基准的表(左外连接就是左边表为基准,右外连接就是右边表为基准)的所有行都显示出来。 =======================================================================================================
好吧,以后就小心用了。
下面就是拼接sql语句的问题啦,这个只学过,但是并没有实际用过,就模仿着我头写的写,哪些地方不懂的就问了他。
$param = ''; $SQL = 'SELECT r.id,r.code,r.name,r.content,r.mobile,r.total_bonus,r.start_date,r.end_date,r.openid,r.date,u.name,u.real_name,s.bloc_id FROM (select id,code,name,content,mobile,total_bonus,start_date,end_date,openid,date from user_customers) as r inner JOIN (select name,code,real_name from user ) as u ON r.code = u.code inner join (select max(bloc_id) as bloc_id , code from service_user_bloc group by code desc) as s on r.code = s.code'; $SQL .= ' WHERE 1 = 1 AND '.$this->param;//本来这里只有一个where 1=1 来连接后面的条件即可,但是因为我要做刚打开页面时数据不显示(即param=“1=2”),点击搜索按钮时才显示出来(即param=“2=2”) if (count($codes) != 0) $param .= ' AND r.code in ('.implode(",", $codes).')'; if($this->mobile!=null) $param .= " AND r.mobile = '".$this->mobile."'"; $SQL .= $param; $SQL .= ' ORDER BY r.date '; 计算记录条数 $countSQL = ' SELECT count(r.code) FROM (select id,code,name,content,mobile,total_bonus,start_date,end_date,openid,date from user_customers) as r inner JOIN (select code from user ) as u ON r.code = u.code inner join (select code from service_user_bloc group by code desc) as s on r.code = s.code'; $countSQL .= ' WHERE 1 = 1 AND '.$this->param; $countSQL .= $param; $count= Yii::app()->db->createCommand($countSQL)->queryScalar();
这样写sql拼接时注意要搜索什么内容,则在要连接的表里面就写哪个字段,还要将通过哪个字段连接的字段也写上去。