guvijur
@guvijur
Практик, кинестетик, ретроград и консерватор

Можно ли в SQL-запросе использовать перебор значений конкретного поля с разделителем и без него?

Доброго всем дня!

Смотрите, есть таблица `tasks` в БД MySQL, имеющая вид:
64019b694dfc4577762457.jpeg

Обращаю внимание на поле "participantsid", в которое заносятся ID участников задачи через запятую или без запятой, если участник один. Эта штука мне досталась по наследству.

Далее переходим к PHP.
Необходимо выбрать из таблицы ту строку, которая соответствует нескольким условиям.
$result = mysqli_query("SELECT * FROM `tasks` WHERE `id`='".$_GET['taskid']."' AND (`customerid` = '".$_GET['userid']."' OR `executorid` = '".$_GET['userid']."' OR `participantsid` LIKE '%".$_GET['userid']."%' OR (`executorid` = '0' AND `executordepid` = '".$_GET['userdep']."')) limit 1");

В запросе:
- `id` - id задачи
- `customerid` - id заказчика
- `executorid` - id исполнителя
- `participantsid` - ID участников задачи, перечисленные через запятую или без, если id один
- `executordepid` - id отдела исполнителя

Сейчас вообще не важно то, на сколько хорошо или плохо написан запрос, важно другое.
Обратите внимание на часть запроса `participantsid` LIKE '%".$_GET['userid']."%' .
Представим, что $_GET['userid'] равен id-шнику "5544", а в поле `participantsid` нет id-шника "5544", НО ЕСТЬ "35544".
В этом случае результат запроса будет получен, поскольку "LIKE %...%" в запросе просто ищет указанную последовательность.

Вопрос заключается в том, можно ли в запросе разбить значение поля по разделителю (в нашем случае разделитель - это запятая) и перебрать среди полученных значений?

Нет, я конечно могу увеличить строки кода в PHP, получить значение поля, потом разбить его с момощью explode, потом перебирать значения массива и сравнивать, и т.д....
Но нельзя ли всё это запихать в SQL-запрос?

Спасибо.
  • Вопрос задан
  • 284 просмотра
Решения вопроса 2
@mletov
"WHERE CONCAT(',', fieldName, ',') LIKE CONCAT('%,' " + тут искомое значение +  "',%')"

Идея куда думать.

Но это с учетом ;)
Сейчас вообще не важно то, на сколько хорошо или плохо написан запрос
Ответ написан
iMedved2009
@iMedved2009
Не люблю людей
Postgres:

“35544” = ANY (string_to_array(participantsid,','))


MySQL

Find_in_set(35544, participantsid);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
В классическом SQL нет возможности работать с массивами и списками внутри одной ячейки. Фактически - это таблица не удовлетворяющая 1НФ и поэтому она не имеет право на жизнь.

Explode. Да, верно. Функция explode разворачивает строки на 90 градусов и позволяет посмотреть на participantid как на дочерние строки от основной таблицы. Но объем обработки как-бы возрастает и если вы передаете эти развернутые стороки на клиента то соотв. растет размер трафика. И работать с такой опухолью не лучше т.к. уникальность по PK/UK переносится на эксплоднутые атрибуты.

Как с этим бороться? Никак. Надо переделывать софт.

Like не работает. Это да. Это - проблема.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы