0

I am working with CodeIgniter and MySQL. I have a job_post table that looks like below:

company_email skill city role
[email protected] 2,3 1,2 5
2,3,12,13 1 6
4,5 1,4 6
[email protected] 1 1 4
[email protected] 1 1 4
1 1 4
[email protected] 1 1,2,4 4

Here I have write query like this :

select jp.*,u.first_name,u.last_name,group_concat(DISTINCT s.skill) as sk,group_concat(DISTINCT c.name) as ct,ufj.fav_id,ufj.is_favourite 
from job_post as jp 
left join industry as ind on ind.ind_id = jp.industry_id 
left join city c ON(FIND_IN_SET(c.city_id, jp.city) > 0) 
left join skill s ON(FIND_IN_SET(s.skill_id, jp.skill) > 0) 
join users as u on u.user_id = jp.emp_id 
left join user_favourite_job as ufj on ufj.job_id = jp.job_id and ufj.user_id = 8 
where jp.city in (2) and jp.is_delete = 1 group by job_id 

When I have pass city id as 1 as jp.city in (1) then it gives a perfect result, but not when I pass city id as 2 as jp.city in (2).

What should I change in my query?

When I passed city id 2 it should display the first and last record from my sample set.

7
  • may be the id not matching plz check your ids Commented Aug 24, 2016 at 8:13
  • use jp.city like '%2%' as in will not give proper result Commented Aug 24, 2016 at 8:19
  • 1
    saving comma separate is not good use one to many relationship Commented Aug 24, 2016 at 8:21
  • @Kool-Mind if i have multiple id then what should I have to do ? like query is not work when I have write jp.city like '%1,2%'. Commented Aug 24, 2016 at 8:26
  • den in such case use like '%1%2%' but remember it will work till 9 digit for 11,12 it will fetch the 1,2 's record Commented Aug 24, 2016 at 8:30

3 Answers 3

1

USe c.city_id instead of using jp.city in where Clause.

select jp.*,u.first_name,u.last_name,group_concat(DISTINCT s.skill) as sk,group_concat(DISTINCT c.name) as ct,ufj.fav_id,ufj.is_favourite 
from job_post as jp 
left join industry as ind on ind.ind_id = jp.industry_id 
left join city c ON(FIND_IN_SET(c.city_id, jp.city) > 0) 
left join skill s ON(FIND_IN_SET(s.skill_id, jp.skill) > 0) 
join users as u on u.user_id = jp.emp_id 
left join user_favourite_job as ufj on ufj.job_id = jp.job_id and ufj.user_id = 8 
where c.city_id in (2) and jp.is_delete = 1 group by job_id
Sign up to request clarification or add additional context in comments.

Comments

1

update where clause

 where jp.city like '%2%'  and jp.is_delete = 1

or use below if it contains 1,2 and 11,12 ,etc

where jp.city like '%1%2%' and jp.city not like '%11%12%'  and jp.is_delete = 1

but using it's not optimal, so please keep id's as one to many relationshiop

1 Comment

This advice should not be used by anyone because using wildcards to match values in a delimited column value will return unintended matches due to partial number matching.
0
  • Because the job_post table (suboptimally) stores city data as a comma-separate string, your query cannot reliably use IN() to filter the records. Fortunately, the joined city table offers city_id as a normalized INT type column.
  • I am a little confused about the is_delete = 1 in this query. The truthy value logically indicates to me that the intention is to return rows which ARE deleted, but that would be unlikely to be a common/useful query. If the column is meant to indicate "active" records, then the column name should probably be name is_active where 1 means active and 0 means not active.
  • It is a bad practice, for performance and maintenance reasons, to store comma-separated values in a database. You should rethink and refactor your database and codebase to store atomic values. Research First Normal Form (1NF).

I took some creative liberties while testing/experimenting with your query and some fabricated data, but below should still contain all of the valuable data and logic from your query. PHPize Demo (without verbose quoting)

To cover cases when $cities is an empty array, prevent and empty IN() expression in your rendered query by writing ?: null. CodeIgniter's query builder class will not add the condition to the SQL if where_in()'s array parameter is null.

public function getJobPosts(int $userId, array $cities = []): array
{
    return $this->db
        ->select([
            'p.job_id',
            'p.emp_id',
            vsprintf('MAX(%s) %s', $this->db->escape_identifiers(['i.industry_name', 'industry_name'])),
            'p.role                            role_id',
            vsprintf('GROUP_CONTACT(DISTINCT %s) %s', $this->db->escape_identifiers(['c.name', 'found_city_name_list'])),
            vsprintf('GROUP_CONTACT(DISTINCT %s) %s', $this->db->escape_identifiers(['s.skill', 'skill_name_list'])),
            vsprintf('MAX(%s) %s', $this->db->escape_identifiers(['u.first_name', 'first_name'])),
            vsprintf('MAX(%s) %s', $this->db->escape_identifiers(['u.last_name', 'last_name'])),
            vsprintf('COALESCE(MAX(%s), 0) %s', $this->db->escape_identifiers(['f.is_favourite', 'is_favourite'])),
        ])
        ->from('job_post p')
        ->join('users u', 'p.emp_id = u.user_id')
        ->join('industry i', 'p.industry_id = i.ind_id', 'left')
        ->join(
            'city c',
            vsprintf(
                'FIND_IN_SET(%s, %s)',
                $this->db->escape_identifiers(['c.city_id', 'p.city'])
            ),
            'left',
            false
        )
        ->join(
            'skill s',
            vsprintf(
                'FIND_IN_SET(%s, %s)',
                $this->db->escape_identifiers(['s.skill_id', 'p.skill'])
            ),
            'left',
            false
        )
        ->join(
            'user_favourite_job f',
            'p.job_id = f.job_id AND f.user_id = ' . $this->db->escape($userId),
            'left'
        )
        ->where_in('c.city_id', $cities ?: null)
        ->where('p.is_delete', 1)
        ->group_by('p.job_id')
        ->get()
        ->result();
}

The fully quoted SQL will render as:

SELECT `p`.`job_id`, `p`.`emp_id`, MAX(`i`.`industry_name`) `industry_name`, `p`.`role` `role_id`, GROUP_CONTACT(DISTINCT `c`.`name`) `found_city_name_list`, GROUP_CONTACT(DISTINCT `s`.`skill`) `skill_name_list`, MAX(`u`.`first_name`) `first_name`, MAX(`u`.`last_name`) `last_name`, COALESCE(MAX(`f`.`is_favourite`), 0) `is_favourite`
FROM `job_post` `p`
JOIN `users` `u` ON `p`.`emp_id` = `u`.`user_id`
LEFT JOIN `industry` `i` ON `p`.`industry_id` = `i`.`ind_id`
LEFT JOIN city c ON FIND_IN_SET(`c`.`city_id`, `p`.`city`)
LEFT JOIN skill s ON FIND_IN_SET(`s`.`skill_id`, `p`.`skill`)
LEFT JOIN `user_favourite_job` `f` ON `p`.`job_id` = `f`.`job_id` AND `f`.`user_id` = 8
WHERE `p`.`is_delete` = 1
GROUP BY `p`.`job_id`

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.