Это может быть сделано в одном выражении SQL. (К сожалению, этот подход не удовлетворяет требованию использовать регулярные выражения. EDIT: см. Последующее описание для неэлегантного и неэффективного подхода, который использует регулярные выражения.)
Мы можем получить количество вхождений символов ' а»в колонке A
и установить колонку B
к графу, с запросом, как это:
UPDATE mytable t
SET t.B = (CHAR_LENGTH(t.A) - CHAR_LENGTH(REPLACE(t.A,'a','')))
Давайте распаковать, что немного. Это заявление UPDATE
, нет предложения WHERE
, поэтому мы собираемся получить доступ и, возможно, обновить каждую строку в mytable
. (Мы назначаем псевдоним таблицы t
. Это не требуется, но мы будем квалифицировать наши более поздние ссылки на столбцы A
и B
с использованием этого псевдонима, чтобы сделать его более понятным для кого-то, читающего инструкцию SQL, что это ссылки на столбцы в таблица.
на следующей строке, мы получили прямое SET
положения, назначив значение столбца B
.
Это следующее выражение, значение мы присваиваем в колонку B
, что мы должны распаковать немного.
Чтобы рассчитать число 'a'
символов, мы можем использовать небольшой трюк: мы знаем, что символ 'a'
имеет ровно один символ в длину.
«Трюк» предназначен для использования функции REPLACE
для поиска всех вхождений символа 'a'
и их удаления (заменяя их нулевой длиной). Затем мы можем сравнить длины (количество символов) двух строк. Разница заключается в количестве символов 'a'
в исходной строке.
В качестве демонстрации того, как работают эти выражения:
SELECT t.foo AS foo
, REPLACE(t.foo,'a','') AS foo_2
, CHAR_LENGTH(t.foo) AS len
, CHAR_LENGTH(REPLACE(t.foo,'a','')) AS len_2
, CHAR_LENGTH(t.foo) - CHAR_LENGTH(REPLACE(t.foo,'a','')) AS `len-len_2`
FROM (SELECT 'a b a a' AS foo
UNION ALL SELECT 'b c a'
UNION ALL SELECT 'b c d'
UNION ALL SELECT 'a '
) t
Возвращенный из этого запроса:
foo foo_2 len len_2 len-len_2
------- ------ ------ ------ ---------
a b a a b 7 4 3
b c a b c 5 4 1
b c d b c d 5 5 0
a 3 2 1
Примечание: что возвращается в основном подсчет количества символов, которые были удален. Поэтому, если мы хотим подсчитать вхождения строки из нескольких символов, для примера: cat
, нам нужно будет это учитывать.
Разделение возвращаемого значения на количество символов в cat
было бы одним из способов сделать это. Или мы могли бы заменить строку cat
строкой длиной в два символа, например. 'xx'
, поэтому разница в длине будет одним символом в каждом случае.
Followup
оригинальный вопрос, который задают, как считать 'а' символов с использованием регулярных выражений. Моя первая мысль заключалась в том, что это невозможно с MySQL REGEXP
, потому что возврат от него равен NULL, 0 или 1. Но немного подумав об этом, это можно сделать, если мы рассчитываем на некоторое конечное число вхождений , Можно было бы проверить, если строка содержит, по меньшей мере, один «а» характер, это довольно просто:
'a b a a' REGEXP 'a'
Это возвращает 1, если он совпадает, и 0, если он не делает. Также возможно проверить, содержит ли строка не менее двух символов 'a'. Это довольно простая задача:
'a b a a' REGEXP 'a.*a'
Если мы складываем результат из двух выражений выше, мы могли бы получить количество либо 0, 1 или 2 для числа «а» символов.
Мы можем повторить тот же шаблон, чтобы увеличить его до 3, 4, 5 и т. Д. «A».
Это не изящно, и мы, конечно же, не хотим узнать, насколько теплый процессор будет делать все эти сравнения. Но он возвращает указанный результат, до некоторого конечного максимального значения. В этом примере шесть. (Строки, содержащие более шести «а» символов будет возвращать счетчик 6.
В качестве демонстрации:
SELECT t.foo
, (t.foo REGEXP CONCAT('.*',REPEAT('a.*',1)))
+ (t.foo REGEXP CONCAT('.*',REPEAT('a.*',2)))
+ (t.foo REGEXP CONCAT('.*',REPEAT('a.*',3)))
+ (t.foo REGEXP CONCAT('.*',REPEAT('a.*',4)))
+ (t.foo REGEXP CONCAT('.*',REPEAT('a.*',5)))
+ (t.foo REGEXP CONCAT('.*',REPEAT('a.*',6)))
AS cnt_a
FROM (SELECT 'a b a a' AS foo
UNION ALL SELECT 'b c a'
UNION ALL SELECT 'b c d'
UNION ALL SELECT 'a '
) t
Вы ищете для ответа только с помощью MySQL Или может PHP участвовать – Guillermo
какие усилия? вы сделали? –
Это поможет вам http://stackoverflow.com/q/14157480/1357033 –