У меня есть таблица, которая содержит два поля. Первый - это name
типа string
. Вторая содержит одну или несколько строк, разделенных запятой (но может содержать одну строку без запятых)
Я хочу создать запрос, чтобы узнать, существует ли строка в поле name
в каждой запятой строке в поле names
.
Пример 1:
---------------------------------------------------------
name names
---------------------------------------------------------
myname xmyname,myname,mynamey
Все строки, разделенные запятыми, содержат слово myname
. Таким образом, запрос не должен возвращать эту строку.
Но, Пример 2:
---------------------------------------------------------
name names
---------------------------------------------------------
myname x,myname,mynamey
Должен быть возвращен. Потому что х не содержит мое имя.
Условие состоит в том, что, если строка в поле name
не существует в каждой разделенных запятыми строках в поле names
, возвращайте строку.
Это не правильно, так как этот запрос не вернет true в примере 2 (который содержит x
, который не содержит myname
).
ВАЖНОЕ ПРИМЕЧАНИЕ:
1) Там не предел, сколько запятых там. Это может быть 0 запятых или больше. Как с этим бороться?
2) Строки являются переменными. Это не всегда тот случай, когда строка myname
. Каждая строка содержит различную строку в поле name
.
4 ответа
Попробуйте это регулярное выражение:
where not concat(names, ',') regexp replace('^([^,]*{n}[^,]*,)*$', '{n}', name)
Как читать шаблон:
Внутренний шаблон [^,]*{n}[^,]*,
означает
- Любой символ без запятой
[^,]
повторяется любое количество раз (*
означает ни раз, ни несколько раз). - сопровождается значением столбца
name
({n}
является заполнителем и будет заменен фактическим значением с помощью функцииreplace()
) - сопровождаемый любым не запятым символом
[^,]
повторяется любое количество раз - с запятой
Внешний шаблон ^({inner_pattern})*$
означает
- Начало строки (
^
) - с последующим повторением внутреннего шаблона любое количество раз
- с последующим концом строки (
$
)
Для этого к столбцу names
(concat(names, ',')
) добавляется запятая, поэтому каждый элемент в строке заканчивается запятой.
Шаблон будет гарантировать, что любой элемент в строке через запятую содержит значение столбца name
. Поскольку вы хотите противоположный результат, мы используем where not ..
.
Этот ответ начался с неправильного решения REGEXP
. Но лучше всего было бы исправить вашу модель данных, чтобы каждое имя в столбце names
находилось в отдельной строке:
name | names
myname | xmyname
myname | myname
myname | mynamey
somename | x
somename | myname
somename | mynamey
Теперь мы можем сделать простой запрос агрегации, чтобы ответить на ваш вопрос:
SELECT name
FROM yourTable
GROUP BY name
HAVING COUNT(CASE WHEN names NOT LIKE CONCAT('%', name, '%') THEN 1 END) > 0;
Предполагая, что «мое имя» не появляется дважды между двумя запятыми, вы можете посчитать запятые и «мое имя»:
where (length(names) - length(replace(names, ','))) >=
length(names) - length(replace(names, 'myname', '12345'))
Вы можете подойти к этому, используя следующий SQL
запрос
SELECT
name, names
FROM
`tablename`
WHERE
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1)
=
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
)/ LENGTH(name)
);
< Сильный > Объяснение : -
Это даст вам количество слов, разделенных ,
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1) -
Ниже приводится соответствие name
в каждой строке и возвращается, сколько раз он нашел
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
) / LENGTH(name)
)
Похожие вопросы
Новые вопросы
mysql
MySQL - это бесплатная система управления реляционными базами данных с открытым исходным кодом (RDBMS), использующая язык структурированных запросов (SQL). НЕ ИСПОЛЬЗУЙТЕ этот тег для других БД, таких как SQL Server, SQLite и т. Д. Это разные БД, которые все используют свои собственные диалекты SQL для управления данными.