У меня проблема с получением результатов из базы данных. У меня есть столбец под названием «Регионы», который в качестве значения содержит все регионы, выбранные пользователем через форму подписки на информационный бюллетень, с запятыми, например «Ближний Восток, Европа».
Я создаю фильтр, который должен будет получить список всех пользователей, которые регистрируются в определенном или нескольких регионах. Пользователи могут выбрать несколько регионов. Из внешнего интерфейса я получаю все выбранные регионы в этом формате «Глобальный, Ближний Восток», который мне нужно использовать в моем SQL-запросе, чтобы найти всех пользователей, у которых глобальный и Ближний Восток выбран в качестве выбранного региона.
Я пытался использовать FIND_IN_SET, но это не очень помогает. Пробовал ниже
$trimmedRegions = rtrim($sortType,', ');
$query = "SELECT * FROM health_alerts_subscribers
WHERE FIND_IN_SET(Regions, $trimmedRegions)";
Любые идеи, как я могу добиться необходимого результата, пожалуйста?
FIND_IN_SET должен работать. Можете ли вы поделиться, как он использовался и как он работал? Я бы пошел по нормализованному маршруту, данные с разделителями всегда будут вызывать проблемы.
@user3783243 user3783243 я обновил свой вопрос. Итак, вы предлагаете хранить все регионы отдельно и иметь такие значения, как «да» или «нет»?
Я думаю, что если вам нужны все строки из глобального, вы можете просто использовать %Global%, поэтому вам нужно будет выполнить запрос для каждого региона.
@ Видал, что, если у меня есть несколько вариантов фильтра, таких как «Глобальный» и «Европа»?
см. мой ответ, вы делаете 2 лайка, где регион похож ("%Global%") и регион похож ("%Europe%")
Вам нужен FIND_IN_SET для каждого отдельного значения. WHERE FIND_IN_SET(Regions, 'Middle East') and FIND_IN_SET(Regions, 'Global'). Я бы сделал другую таблицу, которая имеет отношение к каждой записи.






Вам в значительной степени нужно отформатировать свой sql следующим образом:
SELECT
*
FROM
table
WHERE
regions = 'Europe' or
regions like 'Europe,%' or
regions like '%,Europe' or
regions like '%,Europe,%' or
regions = 'Middle East' or
regions like 'Middle East,%' or
regions like '%,Middle East' or
regions like '%,Middle East,%'
В PHP вам нужно будет перебирать регионы, которые выбрал пользователь, и динамически создавать такой запрос.
Зачем столько лайков, можно поставить один вайлд и в начале и другой в конце. как "%значение%"
@Vidal Я понятия не имею, как выглядит полный список регионов, поэтому, если regions содержит что-то вроде Global,Middle East,Europe,East,Asia, то %East% вернет слишком много результатов.
@Vidal Я уверен, что всю эту ситуацию можно REGEXP_LIKE() решить, но у меня нет терпения, чтобы понять это для OP. Они должны нормализовать свои таблицы и жить дальше. Это будет настоящее дерьмовое шоу, если регион когда-нибудь изменит свое название, заглавные буквы или разделится на несколько регионов или что-то в этом роде.
Я могу предложить такой подход.
SELECT * FROM table
WHERE
region like("%Global%")
and region like ("%Middle East%")
Таким образом, вы можете заставить людей подписаться на них обоих. Вы можете настроить его для своих нужд, очевидно, что это не будет лучшим решением, но вы можете использовать его для создания сводной таблицы на случай, если вы захотите обновить структуру базы данных.
но, как и у меня, у меня будет много запросов, и мне нужно выбрать выбранные результаты, а не статические
Вы хотите получить список подписчиков, чтобы отправить электронное письмо? какова цель увидеть, могу ли я дать вам лучший ответ?
Да, мне нужно будет получить список, который затем будет импортирован в список рассылки по регионам.
хорошо, вы можете сделать запрос [SELECT * FROM table WHERE region like("%Global%")] и получить всех глобальных подписчиков, а затем сохранить их в глобальном списке рассылки, затем сделать запрос для следующего региона Ближний Восток и сын на.
хорошо, но что мне делать с пользователями, у которых несколько регионов в качестве значения? Одним запросом это не приведет к тому, что пользователи
Я думаю, что это не одноразовый запрос, возможно, вам придется запрашивать все разные регионы по отдельности. Пользователи, которые подписаны на несколько регионов, они будут в соответствующем списке рассылки, возможно, в нескольких, как они выбрали.
Итак, если у меня есть все регионы в отдельных столбцах со значением «да» или «нет», я достигну результата? Пользователь должен получить одно письмо со всеми регионами, а не несколько писем.
ОК, теперь я в замешательстве, если вы собираетесь отправить пользователю его / ее регионы, просто запросите таблицу без какого-либо фильтра «где» или «регион». Что вы хотите получить от стола? Какова цель, если вы можете поделиться этим?
Мне нужно отправить пользователю по электронной почте новости о выбранных им регионах, поэтому мне нужно знать, какие пользователи, например, для Европы и Азии, поэтому я экспортирую этот список
Вы отправляете разные электронные письма для каждого региона?
Хорошо, тогда мой 4-й комментарий — это то, что вам нужно. Вам нужно будет сделать запрос для каждого региона.
Я рекомендую то, что говорит пользователь 3783243. Я бы выбрал FIND_IN_SET. Вот пример.
SELECT {columns} FROM {table} WHERE FIND_IN_SET({item_to_search}, {comma-delimited column})
Лучшим способом было бы создать таблицу регионы и добавить свои регионы, а затем создать связанную таблицу с именем regionRelation (пример), а затем добавить идентификатор из региона и таблицы ссылок (как многие ко многим)
Table structure example
Table region
id,region
1, Middle East
2, Global
Table user
id,name
1, John
2, Jan
Table userRegion
userId,regionId
1,1
2,1
SELECT user.id,user.name,region.region from user
left join userRegion ON region.userId=user.id
left join region
where region.region in('Middle East','Global');
В раскрывающемся списке просто выберите все регионы, и когда пользователь выберет те, которые ему нужны, вы сохраните их в таблице пользовательРегион с INSERT INTO userRegion (userid,regionId) (1,2); и так далее.
на место item_to_search что поставить? строка с выбранными областями, разделенными запятыми? и {столбец с разделителями-запятыми} указать имя столбца?
Так вы рекомендуете или нет?
Если у меня будет каждый регион в виде отдельного столбца со значением «да» или «нет», решит ли это мою проблему?
Анаит, тогда вам придется добавлять новый столбец для каждого нового региона. Это не правильный путь. Я рекомендую свой пример выше.
Если пользователь пишет вам письмо и говорит, что его региона нет в списке. Затем все, что вам нужно сделать, это добавить новый регион в таблицу регионов, а все остальное продолжит работать. Вам не придется менять структуру вашей базы данных.
Дело в том, что Регионы фиксированы, их 6 Глобальный, Африка, Средний Восток, Америка, Азия и Европа.
Вы тоже пойдете по этому пути. Технически их 8. Я бы создал логический столбец для каждого и 1 для да/истина и 0 для нет/ложь
Хорошо, и тогда мой запрос будет похож на select, где значение равно 1?
ВЫБЕРИТЕ {столбцы} из {таблицы}, ГДЕ Африка = 1 ИЛИ Азия = 1 и т. д. Вам нужно будет построить запрос на основе выбора пользователя
Если это сработает, пожалуйста, примите ответ. Спасибо и удачи.
Сработало :) Большое спасибо
Для вашего требования нет точной функции, но вы можете использовать приведенный ниже код:
$trimmedRegions = rtrim($sortType,', ');
$trimmedRegionsCollection = explode(",", $trimmedRegions);
$trimmedRegionsRegex = implode("|", $trimmedRegionsCollection); // make string like Global|Middle East
$query = 'SELECT * from health_alerts_subscribers WHERE CONCAT(",", `Regions`, ",") REGEXP ",('.$trimmedRegionsRegex.'),"';
Надеюсь, это поможет вам.
Лучшим решением было бы реорганизовать вашу базу данных и использовать отдельную таблицу и таблицу ссылок для хранения этих данных. Столбцы, содержащие текстовые данные с разделителями, всегда будут вызывать у вас больше сердечной боли в конце, чем потратить несколько минут на правильное проектирование базы данных.