PHP выбирает строку из базы данных, где идентификатор находится в группе идентификаторов

У меня есть 3 идентификатора работодателей: 1, 2 и 3. Я генерирую задачи для каждого, добавляя строку в базу данных и в столбец «for_emp» я вставляю идентификаторы, которым я хочу назначить эту задачу, и все 3 из них могут быть разделены запятая. Итак, допустим, у меня есть задача, а «for_emp» — это «1,2,3», идентификаторы работодателей. Если я хочу выбрать все задачи для идентификатора 2, смогу ли я выбрать из строки с идентификаторами «1,2,3» и просто сопоставить там «2»? Если нет, как вы предлагаете мне вставить свои идентификаторы emp в одну строку в базе данных? БД это MySQL.

Есть идеи ? Спасибо.


person Manny Calavera    schedule 06.10.2010    source источник
comment
Спасибо за ваши ответы. Итак, если я использую таблицу отношений, как я могу отображать данные в своей сетке с идентификатором задачи, именем задачи, назначенными работодателями? Я хотел бы отображать так в одной строке: 1 | Тестовое задание | Emplpoyee 1, Employee 2, Employee 3. Я имею в виду, что мне нужно получить их имена и поместить их в один столбец для отображения.   -  person Manny Calavera    schedule 06.10.2010


Ответы (7)


Не делайте этого так, вам следует нормализовать вашу базу данных.

Что вы хотите сделать, так это иметь таблицу, такую ​​​​как task, а затем task_assignee. task_assignee будет иметь поля task_id и user_id. Если задача имеет, например. трех правопреемников (ID 1, 2 и 3), то вы создадите три строки в таблице task_assignee для этого task, например:

+--------+---------+
|task_id | user_id |
+--------+---------+
|   1    |    1    [
|   1    |    2    [
|   1    |    3    [
+--------+---------+

Затем достаточно запросить таблицу task_assignee, чтобы найти все задачи, назначенные данному пользователю.

Вот пример того, как получить все задачи для user_id 2:

SELECT t.* FROM task AS t INNER JOIN task_assignee AS ta WHERE ta.user_id = 2

РЕДАКТИРОВАТЬ.

Как связанное примечание, даже если вы не сделали это правильно (что я описал в своем ответе ранее), выполнение этого с помощью таких хаков, как LIKE, все равно было бы далеко от оптимального решения. Если вы сохранили список значений, разделенных запятыми, и вам нужно было проверить, например. значение 2 находится в списке, вы можете использовать функцию MySQL FIND_IN_SET:

SELECT * FROM task WHERE FIND_IN_SET(2, for_emp)

Но вы не должны делать этого, если у вас нет выбора (например, вы работаете с чьей-то дерьмовой структурой БД), потому что это более неэффективно и не позволит вам проиндексировать идентификатор сотрудника.

person reko_t    schedule 06.10.2010
comment
Проблема в том, что я хочу перечислить все задачи с деталями. Мне нужно ВЫБРАТЬ все задачи, и для каждой строки задачи мне нужно будет получить каждую запись работодателя для этой задачи в task_assignee, чтобы в итоге я получил идентификатор задачи | Имя работодателя 1, Имя работодателя 2, Имя работодателя 3 | Описание задачи | Срок сдачи. Итак, когда я выбираю строку задачи, мне нужен способ добавить эти 3 имени работодателя в один столбец для отображения. Надеюсь, вы понимаете, что я пытаюсь сказать. Спасибо большое. - person Manny Calavera; 06.10.2010
comment
У вас есть два (хороших) варианта. Первый способ — просто ПРИСОЕДИНИТЬСЯ к таким пользователям, как SELECT t.*, u.* FROM task t INNER JOIN task_assignee ta ON ta.task_id = t.id INNER JOIN user u ON u.id = ta.user_id. Недостатком этого метода является то, что вы также получаете повторяющиеся строки для задач, если у них есть более одного исполнителя, но достаточно просто один раз проанализировать необходимые данные. Второй способ — сначала найти все нужные задачи, а затем второй запрос, чтобы получить всех пользователей для этих задач, например: SELECT u.* FROM user u INNER JOIN task_assignee ta ON ta.user_id = u.id WHERE ta.task_id IN (TASK_IDS) - person reko_t; 06.10.2010

Следующий запрос должен делать то, что вы хотите:

SELECT * FROM tasks WHERE for_emp LIKE '%2%';

Однако имейте в виду, что это также будет соответствовать работодателям 12, 20, 21 и т. д.; так что будьте осторожны, если вы ожидаете, что вы можете получить двузначное число.

Однако другие ответы о перенормировке вашей базы данных определенно предпочтительнее.

person Chowlett    schedule 06.10.2010
comment
Если это необходимо сделать таким образом (чего не следует делать, если данные правильно нормализованы), то SELECT * FROM tasks WHERE CONCAT(',',for_emp,',') LIKE '%,2,%'; или SELECT * FROM tasks WHERE for_emp LIKE '2' ИЛИ ​​for_emp LIKE '%,2,%' ИЛИ ​​for_emp LIKE '2,%' ИЛИ ​​for_emp LIKE '%,2'; - person Mark Baker; 06.10.2010

Ты делаешь это неправильно. Создайте таблицу отношений с двумя полями: employee id и task id. Если одна задача должна быть назначена трем сотрудникам, вставьте три строки в таблицу отношений.

Затем вы используете JOIN для присоединения к таблицам задач, сотрудников и отношений.

person Emil Vikström    schedule 06.10.2010

тогда это не правильное отношение...

Я бы предложил «таблицу сопоставления» для отношения n: m.

employee
  id

task
  id

employeetask
  task_id
  employee_id
person Flask    schedule 06.10.2010

Составьте таблицу для своих работодателей. Вставьте в него свои три строки.

Затем составьте таблицу сопоставления задач работодателям. Если задача назначена трем работодателям, вставьте в эту таблицу три строки. Это базовая работа по взаимодействию объектов.

person Habbie    schedule 06.10.2010

Я бы сделал 2 разные таблицы.

1 с сотрудниками и 1 с задачами.

затем создайте еще одну таблицу, которая объединяет две таблицы, я назову ее «Назначенные задачи».

Затем в назначенных задачах я создаю назначенный идентификатор, номер сотрудника, который является FK для таблицы сотрудников, и идентификатор задачи, который является FK для таблицы Tasks.

Если у сотрудника более 1 задачи. Просто вставьте еще одну строку в назначенную таблицу. ;)

Когда речь идет о базах данных, старайтесь мыслить отдельными сущностями! Объединение этих объектов возможно в другой таблице.

пример sql:

Выберите * из Assignedtasks, где employeeID = 1 даст вам все его/ее задачи. :)

person Emerion    schedule 06.10.2010

Вы можете использовать предложение LIKE '%,2,%' в своем операторе SELECT.

eg:

SELECT * FROM table where for_emp LIKE '%,2,%'

Однако производительность таких запросов, не подлежащих анализу, обычно довольно низкая.

Я бы посоветовал вам вставить строку для каждого сотрудника, которому назначена задача, используя отдельную таблицу TASK_EMPLOYEE_MAPPING с taskId, employeeId в качестве составного первичного ключа.

С таким дизайном ваш запрос будет

SELECT * FROM TASK_EMPLOYEE_MAPPING WHERE employeeId = '2'
person Jagmag    schedule 06.10.2010