Как считать элементы в списке через MySQL - PullRequest
22 голосов
/ 11 августа 2011

Так что мой вопрос довольно прост:

У меня есть столбец в SQL, который представляет собой список, разделенный запятыми (т. Е. cats,dogs,cows,). Мне нужно подсчитать количество элементов в нем, используя только sql (поэтому, какой бы ни была моя функция (давайте вызовем ее FX сейчас) будет работать так:

 SELECT fx(fooCommaDelimColumn) AS listCount FROM table WHERE id=...

Я знаю, что это ошибочно, но вы понимаете (если, к примеру, значение fooCommaDelimColumn равно cats,dogs,cows,, то listCount должен вернуть 4 ...).

Вот и все.

Ответы [ 5 ]

48 голосов
/ 11 августа 2011

Нет встроенной функции для подсчета вхождений подстроки в строку, но вы можете вычислить разницу между исходной строкой и той же строкой без запятых:

LENGTH(fooCommaDelimColumn) - LENGTH(REPLACE(fooCommaDelimColumn, ',', ''))

Он редактировался несколько раз в течение почти 8 лет (вау!), Так что для ясности: в приведенном выше запросе не требуется + 1, потому что данные OP имеют дополнительную запятую.

Хотя в общем случае для строки, которая выглядит следующим образом: foo,bar,baz правильное выражение будет

LENGTH(col) - LENGTH(REPLACE(col, ',', '')) + 1
6 голосов
/ 11 августа 2011

решение zerkms работает, без сомнения об этом.Но ваша проблема создается неверной схемой базы данных, как указал Стив Уэлленс.Вы не должны иметь более одного значения в одном столбце, потому что это нарушает первый нормальный закон.Вместо этого вы должны сделать как минимум две таблицы.Например, предположим, что у вас есть участников , которые владеют животными :

table member (member_id, member_name)
table member_animal (member_id, animal_name)

Еще лучше: поскольку у многих пользователей может быть один и тот же тип животных, вам следуетсоздать 3 таблицы:

table member (member_id, member_name)
table animal (animal_id, animal_name)
table member_animal (member_id, animal_id)

Вы можете заполнить свои таблицы следующим образом, например:

member (1, 'Tomas')
member (2, 'Vincent')
animal (1, 'cat')
animal (2, 'dog')
animal (3, 'turtle')
member_animal (1, 1)
member_animal (1, 3)
member_animal (2, 2)
member_animal (2, 3)

И, чтобы ответить на ваш первоначальный вопрос, это то, что вы бы сделали, если хотитечтобы узнать, сколько животных имеет каждый пользователь:

SELECT member_id, COUNT(*) AS num_animals
FROM member
INNER JOIN member_animal
    USING (member_id)
INNER JOIN animal
    USING (animal_id)
GROUP BY member_id;
5 голосов
/ 23 июля 2013

По предложению @ zerkms.

Если вы не знаете, есть ли запятая или нет, используйте функцию TRIM, чтобы удалить запятые:

(
    LENGTH(TRIM(BOTH ',' FROM fooCommaDelimColumn))
  - LENGTH(REPLACE(TRIM(BOTH ',' FROM fooCommaDelimColumn), ',', ''))
  + 1
) as count

Ссылка: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_trim

Я также согласен с тем, что рефакторинг таблиц является наилучшим вариантом, но если это невозможно сейчас, этот фрагмент может сделать всю работу.

3 голосов
/ 11 января 2016

Эта версия не поддерживает начальные или конечные запятые, но поддерживает пустое значение со счетчиком 0:

IF(values, LENGTH(values) - LENGTH(REPLACE(values, ',', '')) + 1, 0) AS values_count
1 голос
/ 11 августа 2011

Ответ заключается в исправлении схемы базы данных. Это звучит как отношение многих ко многим, для которых требуется соединительная таблица. http://en.wikipedia.org/wiki/Junction_table

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...