Retrieve data for multiple single or reference without like operator

前端 未结 2 1290
遥遥无期
遥遥无期 2021-01-22 11:30

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

相关标签:
2条回答
  • 2021-01-22 11:48

    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.

    0 讨论(0)
  • 2021-01-22 11:59

    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);
    
    0 讨论(0)
提交回复
热议问题