我有两张桌子,如下图所示。在员工表中直接提到技能,我用作另一个表的参考。
问题:
select * from Employee where Skills = "1";
上述查询将显示仅具有“Python”技能的员工记录。当然,它不会显示包含Python的其他组合,例如“1,2”(Python,Java)。如何在不使用类似操作符的情况下实现这一点,因为如果我拥有10,11,21的技能,那么问题就不是它了。
如果您觉得这种使用参考的方式很难或不推荐,请提出您的想法: - )
员工表:
+-----+-------------+-------------+
| id | Name | Skills |
+-----+-------------+-------------+
| 1 | Xyz | 1,2,4 |
| 2 | Xyy | 1,3 |
| 3 | Abc | 1,2,3 |
| 4 | Asd | 1 |
+-----+-------------+-------------+
技能组表:
+-----+-------------+
| id | SkillSet |
+-----+-------------+
| 1 | Python |
| 2 | Java |
| 3 | C |
| 4 | PHP |
+-----+-------------+
答案 0 :(得分:2)
考虑以下
TextView
这个结构与你的结构类似,但是在这些情况下我们可以使用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)
进行查询,但这样效率很低,这里有几个例子
find_in_set
现在适当的规范化会使生活变得更简单,并且会有以下关联表
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 |
+------+------+-----------------+
现在,在这种情况下进行查询会更有效率
mysql> select * from employee_skills;
+------------+----------+
| idemployee | idskills |
+------------+----------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
+------------+----------+
使用最后一种方法可以很容易地完成更复杂的计算。
答案 1 :(得分:1)
正如其他人在评论中所提到的,这不是最有用的设计选择,因为它会让人们为了创建一个简单的CRUD界面与这些值进行交互而啰嗦。
理想情况下:
员工表:
+-----+-------------+
| id | name |
+-----+-------------+
| 1 | Bob |
| 2 | Mary |
+-----+-------------++
技能组表:
+-----+-------------+
| id | skillset |
+-----+-------------+
| 1 | Python |
| 2 | Java |
| 3 | C |
| 4 | PHP |
+-----+-------------+
employee_skillset表:
+-----+---------------+---------------+
| id | employee_id | skillset_id |
+-----+---------------+---------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 4 |
| 4 | 2 | 1 |
| 5 | 2 | 3 |
+-----+---------------+---------------+
然后你可以这样做:
SELECT *
FROM employee e
INNER JOIN employee_skillset es
ON e.id = es.employee_id
WHERE es.skillset_id = "1";
您可以将CRUD界面中的技能组表用作可选择/可编辑的选项。
修改强>
使用 IN 子句也很容易在其中包含一系列技能:
WHERE es.skillset_id IN (1, 3, 4);