检索多个单个或引用的数据,而不像运算符

时间:2015-04-27 09:13:07

标签: php mysql sql

我有两张桌子,如下图所示。在员工表中直接提到技能,我用作另一个表的参考。

问题

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         |
+-----+-------------+

2 个答案:

答案 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);