2016-08-03 2 views
-1

У меня есть две таблицы tbl_user и tbl_projectsзапросы с FIND_IN_SET и массивом

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 запроса для списка из всех проектов те, которые являются матчем с пользовательским навыком

Например, если я выбираю пользователя u1 результат будет как

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

Архитектура неправильно для согласования, Вам необходимо нормализовать 'skills' в другой таблице и имеют ассоциацию с 'user' и' project'. Таким образом, это будет легко фильтровать. – Jeet

ответ

1

Люди лучше, чем я могу помочь вам построить SQL-запрос, чтобы доставить вас туда. Как выглядят ваши таблицы, вам всегда придется создавать сложные запросы, чтобы извлекать полезную информацию. Мой совет, особенно если вы еще на ранней стадии своего проекта, состоит в том, чтобы изменить структуру таблицы, чтобы упростить запрос.

Например, приведенные ниже таблицы отражают информацию в вашем 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: Каждая запись имеет один пользователь и один навык, оба из которых являются внешними ключами к этой таблице (первичные ключи в tbl_users и tbl_skills соответственно). Он должен иметь индекс UNIQUE на (userID,skillID), чтобы предотвратить дублирование записей.

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

tbl_project_skills Каждая запись имеет один проект и один навык, оба из которых являются внешние ключи к этой таблице (первичные ключи в tbl_project и tbl_skills соответственно). Он должен иметь индекс UNIQUE на (pID,skillID), чтобы предотвратить дублирование записей.

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

Идентификационные столбцы в последних двух таблицах не имеют никакой цели. – Strawberry

+0

@Strawberry Нет, что отвечает на конкретный вопрос в OP, но у меня всегда есть первичный ключ в каждой таблице, которую я строю, потому что я хочу, чтобы каждая запись в каждой таблице была однозначно идентифицируемой. Труднее добавить первичный ключ позже, если ваше приложение ему понадобится. – BeetleJuice

+0

У вас есть совершенно хороший естественный ключ в обеих таблицах. Нет необходимости в суррогате. – Strawberry

Смежные вопросы