MySQL: могу ли я сделать for-each для поля, разделенного запятыми? - PullRequest
0 голосов
/ 20 апреля 2010

Я только что столкнулся с проблемой.

Я знаю эти целые числа, $integers: 3,5,15,20.

Я хочу выбрать только строки из этой следующей таблицы, где все INT разделены запятыми из поля NUMBERS.

TABLE: number_table
Uid Numbers
------------------------
1   3,5,15    OK, since all of NUMBERS are in $integers
2   5,15,20   OK, since all of NUMBERS are in $integers
3   3,4,5,15  NOT OK, since 4 is not found in $integers
4   2,15,20,25  NOT OK, since 2 and 25 is not found in $integers

Можно ли сделать «для каждого» в строке, разделенной запятыми, или каким-либо другим способом сделать этот SELECT?

ОБНОВЛЕНИЕ: Похоже, это невозможно. Я оставлю это здесь на некоторое время. Просто намек. При поиске чего-либо в строке, разделенной запятыми, MySQL предоставляет WHEERE что-то IN (строка, разделенная запятыми). То, что я ищу, так или иначе, это пройти через строку через запятую, используя MySQL, но это может оказаться невозможным.

Нечто подобное может сделать это (псевдокод):

SELECT * FROM number_table WHERE each_commaseparated_substring(Numbers , 'IN (3,5,15,20)')

Ответы [ 5 ]

3 голосов
/ 20 апреля 2010

НЕ должно быть полей, разделенных запятыми. Это должны быть строки в связанной таблице.

1 голос
/ 20 апреля 2010

Я не пробовал это, и это немного уродливо и, возможно, медленно, но вы можете попробовать следующее.

3,5,15,20

SELECT * FROM number_table
WHERE Numbers (LIKE '%,3,%' OR LIKE '%3,%') AND Numbers LIKE '%,5,%' AND Numbers LIKE '%,15,%' AND Numbers (LIKE '%,20,%' OR LIKE '%,20%')

Возможно, вы сможете что-то сделать с помощью REGEX. Но, по крайней мере, вы можете использовать хранимую процедуру.

Обновлено для корректности

0 голосов
/ 05 июня 2012

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

SELECT * FROM number_table
WHERE CHAR_LENGTH(Numbers) - CHAR_LENGTH(REPLACE(Numbers, ',', '')) = -1
  + (FIND_IN_SET( 3, Numbers) > 0)
  + (FIND_IN_SET( 5, Numbers) > 0)
  + (FIND_IN_SET(15, Numbers) > 0)
  + (FIND_IN_SET(20, Numbers) > 0)

Чтобы создать это из $integers с помощью PHP:

$sql = "SELECT * FROM number_table
        WHERE CHAR_LENGTH(Numbers) - CHAR_LENGTH(REPLACE(Numbers, ',', '')) = -1";

foreach ($integers as $i) $sql .= " + (FIND_IN_SET($i, Numbers) > 0)";
0 голосов
/ 05 июня 2012

Правильно, короткий ответ - нет, но, несмотря на ненормальные данные, есть уродливые решения, поэтому не рекомендуется.В частности, создайте функцию разделения строки и выполните цикл для каждого значения с помощью хранимой процедуры.

0 голосов
/ 20 апреля 2010

Возможно, попробуйте использовать конкататный код, используя PHP и функцию implode().

...