使用 FIND_IN_SET 和数组查询

Query with FIND_IN_SET and array

我有两个表 tbl_usertbl_projects

tbl_user
+-----+------+--------+
| id  | name | skills |
+-----+------+--------+
|  u1 | x    | s1,s2  |
|  u2 | y    | s2,s3  |
|  u3 | z    | s3,s1  |
+-----+------+--------+

tbl_projects
+-----+--------+
| id  | kills  |
+-----+--------+
|  p1 | s2     |
|  p2 | s1,s3  |
|  p3 | s3     |
+-----+--------+

对于我的应用程序,我想要一个 sql 查询来列出所有与用户技能相匹配的项目

例如,如果我 select 用户 u1 结果将类似于

+-----+--------+
| id  | kills  |
+-----+--------+
|  p1 | s2     |
|  p2 | s1,s3  |
+-----+--------+

比我优秀的人可以帮助您构建 SQL 查询以帮助您实现目标。尽管您的 table 看起来如此,但您总是必须构建复杂的查询才能提取有用的信息。我的建议是更改 table 结构以使查询更容易,尤其是如果您仍处于项目的早期阶段。

例如,下面的 table 以一种结构反映了您 OP 中的信息,这将使您的生活更加轻松。

tbl_users:保存与每个用户具有一对一关系的详细信息

userID|name|email...
 u1   |  x | ...
 u2   |  y | ...
 u3   |  z | ...

tbl_skills:与各技能一一对应的详情

skillID
s1
s2
s3

tbl_projects:与每个项目有一对一关系的详情

pID|   title   | deadline
p1 | project a | 2016-08-15
p2 | project b | 2017-01-01
p3 | project c | 2015-08-22

tbl_user_skills:每条记录有一个用户和一个技能,都是这个table的外键([=17中的主键=] 和 tbl_skills)。它应该在 (userID,skillID) 上有一个 UNIQUE 索引以防止重复条目。

userID|skillID
 u1   | s1
 u1   | s2
 u2   | s2
 u2   | s3
 u3   | s1
 u3   | s3

tbl_project_skills每条记录有一个项目和一个技能,都是这个table的外键([=21=中的主键] 和 tbl_skills 分别)。它应该在 (pID,skillID) 上有一个 UNIQUE 索引以防止重复条目。

pID|skillID
p1 |s2
p2 |s1
p2 |s3
p3 |s3

以这种方式组织所有内容后,您的查询将更快,构建起来也更简单。事实上,如果你了解位标志操作,你可以大大压缩它(例如:将用户的所有技能作为 tbl_users 中的一个字段,但你会使用位而不是 s1,s2)。

获取用户u1技能的所有项目:

SELECT p.pID, p.title
FROM tbl_projects p
LEFT JOIN tbl_project_skills ps ON p.pID = ps.pID
LEFT JOIN tbl_user_skills us ON ps.skillID = us.skillID
WHERE us.userID='u1'
GROUP BY p.pID

结果

pID| title
p1 | project a
p2 | project b