使用 FIND_IN_SET 和数组查询
Query with FIND_IN_SET and array
我有两个表 tbl_user
和 tbl_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
我有两个表 tbl_user
和 tbl_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