I have two tables, which looks like below. In the employee table instead mentioning the skills directly, I\'m using as reference from another table.
Question
Consider the following
mysql> select * from employee ;
+------+------+--------+
| id | name | skills |
+------+------+--------+
| 1 | xyz | 1,2,4 |
| 2 | abc | 1,3 |
| 3 | lmn | 1,2,3 |
+------+------+--------+
3 rows in set (0.00 sec)
mysql> select * from skillset ;
+------+----------+
| id | skillset |
+------+----------+
| 1 | Python |
| 2 | Java |
| 3 | C |
| 4 | PHP |
+------+----------+
4 rows in set (0.00 sec)
This structure is similar to yours and to do query in these situation we can however use find_in_set
but thats pretty inefficient , here are few examples
mysql> select e.id,
e.name,
group_concat(s.skillset) as skillset
from employee e join skillset s
on find_in_set(s.id,e.skills) > 0
where find_in_set(1,e.skills) > 0
group by e.id ;
+------+------+-----------------+
| id | name | skillset |
+------+------+-----------------+
| 1 | xyz | Python,Java,PHP |
| 2 | abc | C,Python |
| 3 | lmn | Java,Python,C |
+------+------+-----------------+
3 rows in set (0.00 sec)
select e.id,
e.name,
group_concat(s.skillset) as skillset
from employee e
join skillset s on find_in_set(s.id,e.skills) > 0
where find_in_set(2,e.skills) > 0 group by e.id ;
+------+------+-----------------+
| id | name | skillset |
+------+------+-----------------+
| 1 | xyz | Python,PHP,Java |
| 3 | lmn | C,Java,Python |
+------+------+-----------------+
Now a proper normalization would make life much simpler and will have the following association table
mysql> select * from employee_skills;
+------------+----------+
| idemployee | idskills |
+------------+----------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
+------------+----------+
Now doing query will be much more efficient in this case
mysql> select e.id,
e.name,
s.skillset from employee e
join employee_skills es on es.idemployee = e.id
join skillset s on s.id = es.idskills where s.id = 1 ;
+------+------+----------+
| id | name | skillset |
+------+------+----------+
| 1 | xyz | Python |
| 2 | abc | Python |
| 3 | lmn | Python |
+------+------+----------+
Using the last approach more complex calculations could be done pretty easily.
As mentioned by others in the comments, this is not the most useful design choice as it would make it long winded to create a simple CRUD interface to interact with these values.
You would have ideally:
employee table:
+-----+-------------+
| id | name |
+-----+-------------+
| 1 | Bob |
| 2 | Mary |
+-----+-------------++
skillset table:
+-----+-------------+
| id | skillset |
+-----+-------------+
| 1 | Python |
| 2 | Java |
| 3 | C |
| 4 | PHP |
+-----+-------------+
employee_skillset table:
+-----+---------------+---------------+
| id | employee_id | skillset_id |
+-----+---------------+---------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 4 |
| 4 | 2 | 1 |
| 5 | 2 | 3 |
+-----+---------------+---------------+
Then you could do:
SELECT *
FROM employee e
INNER JOIN employee_skillset es
ON e.id = es.employee_id
WHERE es.skillset_id = "1";
You could use the skillset table in the CRUD interface as selectable / editable options.
EDIT:
It's easy enough to include a range of skills within this too using the IN clause:
WHERE es.skillset_id IN (1, 3, 4);