I post an array of skills from the form and i need to fetch list of candidates list related to the elements in array in codeigniter.
Controller
$data = array(
"mode" => $this->input->post("mode"),
"designation" => $this->input->post("designation"),
"notice_period" => $this->input->post("notice_period"),
"skill" => $this->input->post("skills"),
"cities" => $this->input->post("city")
);
$this->load->model("search_model");
$this->load->model("candidate_model");
$data["candidate"] = $this->search_model->fetch_candidate($data);
$data["designation"] = $this->candidate_model->fetch_designation();
$this->load->view('candidate_profiles', $data);
model
function fetch_candidate($data)
{
$mode = $data['mode'];
$designation = $data['designation'];
$notice_period = $data['notice_period'];
$skill = $data['skill'];
$skills = join(",",$skill);
$city = $data['cities'];
$query = $this->db->query("SELECT DISTINCT(U.user_id), U.firstname, U.lastname, U.username, U.usertype, U.email, U.phone, U.address, U.profile_image, C.name AS country,C.id AS countryid, S.name AS state,S.id AS stateid, A.housename, A.street, A.area, A.po, A.city, CJ.designation, CJ.resume, CJ.biography, CJ.hiring_mode, CJ.notice_period, CJ.current_CTC, CJ.expected_CTC, D.designation_id AS desig, D.designation AS desig_name
FROM users AS U
LEFT JOIN address AS A ON U.user_id=A.cand_id
LEFT JOIN cand_job_details AS CJ ON CJ.cand_id=U.user_id
LEFT JOIN designations AS D ON D.designation_id=CJ.designation
LEFT JOIN countries AS C ON C.id=A.country
LEFT JOIN states AS S ON S.id=A.state
LEFT JOIN user_skills AS US ON U.user_id=US.user_id
LEFT JOIN user_interested_cities AS UC ON U.user_id=UC.user_id
WHERE D.designation LIKE '$designation' && (CJ.hiring_mode='2' || CJ.hiring_mode='$mode') && CJ
.notice_period<='$notice_period' && UC.city='$city' && US.skill IN(".implode(",", $skills).")
");
return $query;
}
How to implement this on codeigniter?
Thanks in advance
You need try to add ' around each argument. After it should looks like IN ('PHP','AngularJS'), because it is a string value and datatype is varchar as well.
$skills = "'";
foreach($skill as $item) {
$skills .= $item."',";
}
$skills = trim($skills,",")
Codeigniter comes with a built in Querybuilder - i strongly suggest to use it, because it makes your life much easier, and protects you against SQL injections - which is clearly a problem in your case.
Try the following
function fetch_candidate($data)
{
$this->db
->select('SELECT DISTINCT(U.user_id), U.firstname, U.lastname, U.username, U.usertype, U.email, U.phone, U.address, U.profile_image, C.name AS country,C.id AS countryid, S.name AS state,S.id AS stateid, A.housename, A.street, A.area, A.po, A.city, CJ.designation, CJ.resume, CJ.biography, CJ.hiring_mode, CJ.notice_period, CJ.current_CTC, CJ.expected_CTC, D.designation_id AS desig, D.designation AS desig_name')
->from('users U')
->join('address A', 'U.user_id=A.cand_id', 'left')
->join('cand_job_details CJ', 'CJ.cand_id=U.user_id', 'left')
->join('designations D', 'D.designation_id=CJ.designation', 'left')
->join('countries C', 'C.id=A.country', 'left')
->join('states S', 'S.id=A.state', 'left')
->join('user_skills US', 'U.user_id=US.user_id', 'left')
->join('user_interested_cities UC', 'U.user_id=UC.user_id', 'left');
if (isset($data['designation']) && !empty($data['designation']))
{
$this->db->like('D.designation', $data['designation']);
}
if (isset($data['mode']) && !empty($data['mode']))
{
$this->db
->group_start()
->where('CJ.hiring_mode', 2)
->or_where('CJ.hiring_mode', $data['mode'])
->group_end();
}
if (isset($data['notice_period']) && !empty($data['notice_period']))
{
$this->db->where('CJ.notice_period <=', $data['notice_period']);
}
if (isset($data['city']) && !empty($data['city']))
{
$this->db->where('UC.city', $data['city']);
}
if (isset($data['skills']) && is_array($data['skills']))
{
$this->db->where_in('US.skill', $data['skills']);
}
return $this->db->get();
}
Related
I want to join multiple tables, as in my picture:
Here is my code:
$this->db->select('
pt2.turl as `p_img`,
p.title as `p_title`,
p.text as `p_text`,
p.create as `p_date`,
pt3.turl as `c_img`,
u.name as `c_name`,
c.text as `c_text`,
c.create as `c_date`
');
$this->db->from('posts as p, users as u, photos as pt2, photos as pt3');
$this->db->join('comments as c', 'p.id=c.pid AND u.id=c.uid');
$this->db->join('posts as p2', 'p2.pid=pt2.id', 'rihgt');
$this->db->join('users as u2', 'u2.photoid=pt3.id', 'right');
$this->db->order_by('c.id', 'DESC');
$this->db->limit('7');
$qry = $this->db->get();
return $qry->result();
If I understand you correctly, this is kind of what you're looking for. I haven't tried it out so it may not be exact, but you shouldn't need to make 2 table associations (pt2 and pt3) for the same table in the join. Just Include them in the select and join on the unique ID's
The "Left" is a join that is centered around you're left table so everything hangs off of that. Since you are joining the users table before the photo table, you should be able to join on its columns.
Hope this helps. Let me know if I missed something. :)
$select = array(
pt2.turl as `p_img`,
p.title as `p_title`,
p.text as `p_text`,
p.create as `p_date`,
pt2.turl as `c_img`,
u.name as `c_name`,
c.text as `c_text`,
c.create as `c_date`
);
//Set tables to variables. Just makes it easier for me
$postsTable = "posts as p"; //This will be your left table.
$userTable = "Users as u";
$commentsTable = "comments as c";
$photosTable = "photos as pt2";
$this
->db
->select($select)
->from($postsTable)
->join($userTable, "p.uid = u.id", "left")
->join($commentsTable, "p.cid = c.id", "left")
->join($photosTable, "u.photoid = pt2.id", "left")
->get();
I solved this problem myself
It would be like this:
$select= array (
//'*',
'pt.turl p_img',
'p.title p_title',
'p.text p_text',
'p.create p_date',
'pt2.turl c_img',
'c.text c_text',
'u.name c_name',
'c.create c_date'
);
$from = array (
'posts p'
);
$qry = $this
->db
->select($select)
->from($from)
->join('comments c', 'c.pid=p.id')
->join('photos pt', 'pt.id=p.pid')
->join('users u', 'u.id=c.uid')
->join('photos pt2', 'u.photoid=pt2.id')
->order_by('c.create', 'DESC')
->limit('7')
->get();
return $qry->result();
I would like to know how can i transform this query into eloquent. Im having some troubles displaying those "counts" fields.
$resultados = DB::select( DB::raw("
Select * From (
Select
P.*,
count(distinct PP.id) as countProduct,
count(distinct C.id) as countCity,
count(distinct CO.id) as countCountry,
count(distinct CON.id) as countContinent
From
packages P
Inner join citie_package CP
on P.id = CP.package_id
Inner join cities C
on CP.city_id = C.id
Inner Join countries CO
on C.country_id = CO.id
Inner join continents CON
on CO.continent_id = CON.id
Inner Join product_package PP
on P.id = PP.package_id
where
$whereCondition
group by
P.id,
P.name,
P.image,
P.days,
P.operator_id,
P.badge,
P.price,
P.brochure,
P.lodging,
P.itinerary,
P.services,
P.observations,
P.offer,
P.featured,
P.validity,
P.created_at,
P.updated_at,
P.invisible,
P.operationdates
) as pepe
where
$subWhereCondition
"));
For now the query is working good (on my localhost), when i uploaded it to production i found the following problem:
"SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
So im deciding to built it again but on this time using eloquent.
Thanks!!
Edit:
Before i tried something like this:
$resultado = DB::table('packages')
->join('product_package','packages.id','=','product_package.package_id')
->join('products','products.id','=','product_package.product_id')
->join('citie_package','packages.id','=','citie_package.package_id')
->join('cities','cities.id','=','citie_package.city_id')
->join('countries','countries.id','=','cities.country_id')
->join('continents','continents.id','=','countries.continent_id')
->where(function($resultado) use ($input){
if(isset($input['products'])){
$resultado->whereIn('products.id',$input['products']);
}
if(isset($input['cities'])){
$resultado->whereIn('cities.id',$input['cities']);
}
if(isset($input['countries'])){
$resultado->whereIn('countries.id',$input['countries']);
}
if(isset($input['continents'])){
$resultado->whereIn('continents.id',$input['continents']);
}
if(isset($input['operator'])){
$resultado->whereIn('packages.operator_id',$input['operator']);
}
})
->where('days', '>=', $input['durationFrom'])
->where('days', '<=', $input['durationTo'])
->where('price', '>=', str_replace('$','',str_replace('.','',$input['costFrom'])))
->where('price', '<=', str_replace('$','',str_replace('.','',$input['costTo'])))
->select(
array(
DB::raw('packages.*'),
DB::raw('COUNT(distinct cities.id) as count')
)
)->get()
return $resultado;
Using groupBy!
Finally i figured it out :D:
This is the final code
$resultados = Package::
join('product_package','packages.id','=','product_package.package_id')
->join('products','products.id','=','product_package.product_id')
->join('citie_package','packages.id','=','citie_package.package_id')
->join('cities','cities.id','=','citie_package.city_id')
->join('countries','countries.id','=','cities.country_id')
->join('continents','continents.id','=','countries.continent_id')
->where(function($resultado) use ($input){
if(isset($input['products'])){
$resultado->whereIn('products.id',$input['products']);
}
if(isset($input['cities'])){
$resultado->whereIn('cities.id',$input['cities']);
}
if(isset($input['countries'])){
$resultado->whereIn('countries.id',$input['countries']);
}
if(isset($input['continents'])){
$resultado->whereIn('continents.id',$input['continents']);
}
if(isset($input['operator'])){
$resultado->whereIn('packages.operator_id',$input['operator']);
}
})
->groupBy('packages.id')
->where('days', '>=', $input['durationFrom'])
->where('days', '<=', $input['durationTo'])
->where('price', '>=', str_replace('$','',str_replace('.','',$input['costFrom'])))
->where('price', '<=', str_replace('$','',str_replace('.','',$input['costTo'])))
->select( array(
DB::raw('packages.*'),
DB::raw('COUNT(distinct cities.id) as CountCity ,COUNT(distinct continents.id) as CountContinent, COUNT(distinct countries.id) as CountCountry, COUNT(distinct products.id) as CountProduct') ) )
->get();
if(isset($input['cities'])) {
$resultados = $resultados->filter(function ($resultado) use ($input) {
return $resultado->CountCity == count($input['cities']);
});
}
if(isset($input['countries'])) {
$resultados = $resultados->filter(function ($resultado) use ($input) {
return $resultado->CountCountry == count($input['countries']);
});
}
if(isset($input['continents'])) {
$resultados = $resultados->filter(function ($resultado) use ($input) {
return $resultado->CountContinent == count($input['continents']);
});
}
if(isset($input['products'])) {
$resultados = $resultados->filter(function ($resultado) use ($input) {
return $resultado->CountProduct == count($input['products']);
});
}
Thanks!
I want To combine AND condition with OR condition in codeigniter SQL query
i am creating a where condition depending on the users input.
when a user select rent, iam passing OR condition inside WHERE(AND) like this $where['p.contract_id = 3 OR p.contract_id']=2;.
here is my code..
$where = array('p.status' => 1, 'pi.order' => 1);
if(!$fil['city'] == 0){
$where['p.city_id']=$fil['city'];
}
if(!$fil['area'] == 0){
$where['p.area_id']=$fil['area'];
}
if(!$fil['type'] == 0){
$where['p.type_id']=$fil['type'];
}
if(!$fil['bed'] == 0 && !$fil['bed']== 10){
$where['pd.bed']=$fil['bed'];
}
if($fil['bed']== 10){
$where['pd.bed >']=$fil['bed'];
}
if(!$fil['bath'] == 0 && !$fil['bath'] == 10){
$where['pd.bath']=$fil['bath'];
}
if($fil['bath'] == 10){
$where['pd.bath >']=$fil['bath'];
}
if(!is_null($fil['rent'])){
$where['p.contract_id = 3 OR p.contract_id']=2;
}
if(!is_null($fil['sale'])){
$where['p.contract_id']=1;
}
if(!$fil['price_from'] ==""){
$where['pd.price >']=$fil['price_from'];
}
//real query
$this->db->select('p.*, pd.title, pd.price, pd.bed, pd.bath, pd.size, pd.size_type, pd.full_description,
pi.name as image, pi.order, a.name as area, t.name as type_name, ct.name as contract_type, pv.views as views,
c.name as city');
$this->db->from('property p');
$this->db->join('property_detail pd', 'pd.property_id=p.property_id', 'left');
$this->db->join('property_image pi', 'pi.property_id=p.property_id', 'left');
$this->db->join('type t', 't.type_id=p.type_id', 'left');
$this->db->join('contract_type ct', 'ct.con_typ_id=p.contract_id', 'left');
$this->db->join('property_views pv', 'pv.property_id=p.property_id', 'left');
$this->db->join('area a', 'a.area_id=p.area_id', 'left');
$this->db->join('city c', 'c.city_id=p.city_id', 'left');
$this->db->where($where);
$this->db->order_by('p.property_id','desc');
$this->db->limit($config['per_page'], $this->uri->segment(3));
$query = $this->db->get();
$result = $query->result();
return $result;
ERROR
Error Number: 1064
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 '2' at line 12
SELECT 'p'.*,
'pd'.'title',
'pd'.'price',
'pd'.'bed',
'pd'.'bath',
'pd'.'size',
'pd'.'size_type',
'pd'.'full_description',
'pi'.'NAME' AS 'image',
'pi'.'ORDER',
'a'.'NAME' AS 'area',
't'.'NAME' AS 'type_name',
'ct'.'NAME' AS 'contract_type',
'pv'.'views' AS 'views',
'c'.'NAME' AS 'city'
FROM 'property' 'p'
LEFT JOIN 'property_detail' 'pd'
ON 'pd'.'property_id'='p'.'property_id'
LEFT JOIN 'property_image' 'pi'
ON 'pi'.'property_id'='p'.'property_id'
LEFT JOIN 'type' 't'
ON 't'.'type_id'='p'.'type_id'
LEFT JOIN 'contract_type' 'ct'
ON 'ct'.'con_typ_id'='p'.'contract_id'
LEFT JOIN 'property_views' 'pv'
ON 'pv'.'property_id'='p'.'property_id'
LEFT JOIN 'area' 'a'
ON 'a'.'area_id'='p'.'area_id'
LEFT JOIN 'city' 'c'
ON 'c'.'city_id'='p'.'city_id'
WHERE 'p'.'status' = 1
AND 'pi'.'ORDER' = 1
AND 'p'.'contract_id' = 3
OR p.contract_id 2
i Know very Well this error is Caused because if this $where['p.contract_id = 3 OR p.contract_id']=2;. Can some one help me to pass this where condition with OR statement in codeigniter. Tnx..
This might work for you. Here I've placed or_where() and where() after where condition which checks for your if condition
$this->db->distinct();
$this->db->select('p.*, pd.title, pd.price, pd.bed, pd.bath, pd.size, pd.size_type, pd.full_description,
pi.name as image, pi.order, a.name as area, t.name as type_name, ct.name as contract_type, pv.views as views,
c.name as city',false);
$this->db->from('property p');
$this->db->join('property_detail pd', 'pd.property_id=p.property_id', 'left');
$this->db->join('property_image pi', 'pi.property_id=p.property_id', 'left');
$this->db->join('type t', 't.type_id=p.type_id', 'left');
$this->db->join('contract_type ct', 'ct.con_typ_id=p.contract_id', 'left');
$this->db->join('property_views pv', 'pv.property_id=p.property_id', 'left');
$this->db->join('area a', 'a.area_id=p.area_id', 'left');
$this->db->join('city c', 'c.city_id=p.city_id', 'left');
$this->db->where($where);
if(!is_null($fil['rent'])){
$this->db->where('p.contract_id','3');
$this->db->or_where('p.contract_id','2');
}
$this->db->order_by('p.property_id','desc');
$this->db->limit($config['per_page'], $this->uri->segment(3));
$query = $this->db->get();
$result = $query->result();
return $result;
Output
SELECT `p`.*, `pd`.`title`, `pd`.`price`, `pd`.`bed`, `pd`.`bath`, `pd`.`size`, `pd`.`size_type`, `pd`.`full_description`, `pi`.`name` as image, `pi`.`order`, `a`.`name` as area, `t`.`name` as type_name, `ct`.`name` as contract_type, `pv`.`views` as views, `c`.`name` as city FROM (`property` p) LEFT JOIN `property_detail` pd ON `pd`.`property_id`=`p`.`property_id` LEFT JOIN `property_image` pi ON `pi`.`property_id`=`p`.`property_id` LEFT JOIN `type` t ON `t`.`type_id`=`p`.`type_id` LEFT JOIN `contract_type` ct ON `ct`.`con_typ_id`=`p`.`contract_id` LEFT JOIN `property_views` pv ON `pv`.`property_id`=`p`.`property_id` LEFT JOIN `area` a ON `a`.`area_id`=`p`.`area_id` LEFT JOIN `city` c ON `c`.`city_id`=`p`.`city_id` WHERE `p`.`status` = 1 AND `pi`.`order` = 1 AND `p`.`contract_id` = '3' OR `p`.`contract_id` = '2' ORDER BY `p`.`property_id` desc LIMIT 0
You can try something like that:
$this->db->where('(p.contract_id = 3 OR p.contract_id =2) AND (...) ', NULL, FALSE);
The third parameter tells ci that it should not try to protect your field names. You will have to care yourself for injection problems.
SELECT `p`.*, `pd`.`title`, `pd`.`price`, `pd`.`bed`, `pd`.`bath`, `pd`.`size`, `pd`.`size_type`, `pd`.`full_description`, `pi`.`name` as `image`, `pi`.`order`, `a`.`name` as `area`, `t`.`name` as `type_name`, `ct`.`name` as `contract_type`, `pv`.`views` as `views`, `c`.`name` as `city` FROM `property` `p` LEFT JOIN `property_detail` `pd` ON `pd`.`property_id`=`p`.`property_id` LEFT JOIN `property_image` `pi` ON `pi`.`property_id`=`p`.`property_id` LEFT JOIN `type` `t` ON `t`.`type_id`=`p`.`type_id` LEFT JOIN `contract_type` `ct` ON `ct`.`con_typ_id`=`p`.`contract_id` LEFT JOIN `property_views` `pv` ON `pv`.`property_id`=`p`.`property_id` LEFT JOIN `area` `a` ON `a`.`area_id`=`p`.`area_id` LEFT JOIN `city` `c` ON `c`.`city_id`=`p`.`city_id`
WHERE `p`.`contract_id` IN ('3', '2') AND `p`.`status` = 1 AND `pi`.`order` = 1 ;
How to join using table model
model name:User
Query:
SELECT
DISTINCT (u.UserID),
u.usertypeid,
u.UserName
FROM user u, lkusergroup lug, `group` g
WHERE u.userid = lug.userid
AND g.groupid = lug.groupid
AND UserName = 'abcd';
Something like this but using model
$user = Yii::app()->db->createCommand()
->select('*')
->from('user u')
->join('lkusergroup lug', 'u.userid = lug.userid')
->join('group g', 'g.groupid = lug.groupid')
->where('UserName=:UserName', array(':UserName'=>$this->username))
->queryRow();
I have a function that creates a query to my db, like this:
public function getList($u, $t, $ls, $lf) {
return $this->getEntityManager()
->createQuery('
SELECT
o,
u,
g,
r,
t,
p
FROM GameShelfUsersBundle:Own o
LEFT JOIN o.user u
LEFT JOIN o.game g
LEFT JOIN o.rate r
LEFT JOIN o.typo t
LEFT JOIN o.platforms p
WHERE u.id = :user
AND o.typo = :type
ORDER BY o.updated DESC
')
->setParameters(array(
'user' => $u,
'type' => $t
))
->setMaxResults($lf)
->setFirstResult($ls)
->getResult();
}
My problem is, how to set :type to be not in? I mean, I wanted to use it like this:
$type = '!= 1'
...
AND o.typo :type
...
'type' => $type
But it didn't worked at all. Using $type = -1 doesn't help either. Is there any way, other than creating if/else statement and duplicating query?
Why don't you use a query builder??
In that way you can easily customize your query, depending on some condition.
This is an example:
$q = $this
->createQueryBuilder('foo')
->select('foo')
->leftJoin('foo.bar', 'foobar')
->leftJoin('foobar.bar', 'foobarbar')
;
if($myVar > 0)
{
$q->where('foobarbar.var = :myVar');
}
else
{
$q->where('foobarbar.var = :staticValue');
}
[...]
Remember to call return $q->getResult(); at the end