Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Добрый день.
Необходимо реализовать ряд запросов следующего типа: есть таблица с полем типа text, в нём хранится текст примерно следующего плана:
[{"id":"1","value":"1"},{"id":"2","value":"2"},{"id":"3","value":"22"},{"id":"4","value":"222"},{"id":"5","value":"7"}]
Т.е. порядковый номер (id) и некоторое значение.
Надо сделать запросы по простому вхождению подстроки, тут всё просто - используем like '%%'.
Второй тип запросов более сложный: туда передаётся максимальное и минимальное число (в некоторых случаях только максимальное или только минимальное) и надо найти для определенных id (допустим id = 3 и id = 4) значения (value), которые входят в переданный диапазон.
Вроде как есть регулярные выражения в mysql, стоит ли с ними работать или они сильно тормозные?
В БД будет максимум 200-250 строк с такими полями.
Неактивен
Вообще я бы на вашем месте денормализовал немножко таблицу и хранил значения id и value в отдельных столбцах.
Регулярные выражения здесь не помогут, т.к. в MySQL они не умеют захватывать части строк, а позволяют лишь проверить, соответствует ли строка заданному выражению.
Однако решение существует. Оно довольно громоздкое и весьма ресурсоемкое: запрос не будет использовать индексы вообще, т.е. понадобится полный скан таблицы; кроме того, при его выполнении понадобится создание временной таблицы. Впрочем, при ваших объемах это не страшно, так что приступим.
Для начала рассмотрим задачу, как из строки вида '{"id":"N","value":"M"}' получить N и M. Один из возможных путей - через функцию SUBSTRING_INDEX().
(он не очень гибкий, но в данном случае один из наиболее простых и быстрых).
Здесь используем такое свойство формата ваших записей, каждая запись содержит 8 кавычек, причем N - между 3-ой и 4-ой, а M - между 6-ой и 7-ой.
SUBSTRING_INDEX( '{"id":"N","value":"M"}', '"', 4 ) даст строку '{"id":"N'. Соответственно, нужно еще раз применить SUBSTRING_INDEX(), чтобы получить часть [уже новой] строки справа от последней кавычки: для этого нужно в качестве третьего аргумента передать -1 (т.е. "справа от первой кавычки с конца").
Поэтому число N (т.е. значение id) даст вот такое выражение:
SELECT
SUBSTRING_INDEX(
SUBSTRING_INDEX('{"id":"N","value":"M"}', '"', 4),
'"',
-1 )
Соответственно, для M нужно 8 вместо 4.
В общем, требуемый запрос будет примерно таким:
SELECT *
FROM table
WHERE
SUBSTRING_INDEX( SUBSTRING_INDEX(text, '"', 4), '"', -1 ) IN (список id)
AND
SUBSTRING_INDEX( SUBSTRING_INDEX(text, '"', 8), '"', -1 ) BETWEEN min AND max
Если нужно для id1 min1 и max1, для id2 - min2 и max2, то придется конструировать соответствующие условия и объединять через OR:
SELECT *
FROM table
WHERE
(
SUBSTRING_INDEX( SUBSTRING_INDEX(text, '"', 4), '"', -1 ) = id1
AND
SUBSTRING_INDEX( SUBSTRING_INDEX(text, '"', 8), '"', -1 ) BETWEEN min1 AND max1
)
OR
(
SUBSTRING_INDEX( SUBSTRING_INDEX(text, '"', 4), '"', -1 ) = id2
AND
SUBSTRING_INDEX( SUBSTRING_INDEX(text, '"', 8), '"', -1 ) BETWEEN min2 AND max2
)
OR
...
Неактивен
Страниц: 1