http://blog.idealmind.com.br/mysql/how-to-use-string-as-array-in-mysql-and-work-with/

вопрос следует изMYSQL объединяет набор результатов уничтоженных результатов во время IN () в предложении where?

Итак, короткая версия вопроса. Как превратить строку, возвращаемую GROUP_CONCAT, в список выражений, разделенных запятыми, который IN () будет обрабатывать как список из нескольких элементов для зацикливания?

Нотабене Документы MySQL, по-видимому, ссылаются на «(запятые, разделенные, списки)», используемые IN () как «списки выражений», и, что интересно, страницы в IN () кажутся более или менее единственными страницами в документах MySQL для когда-либо обращаться к спискам выражений. Поэтому я не уверен, будут ли здесь полезны функции, предназначенные для создания массивов или временных таблиц.

Длинная примерная версия вопроса: из БД с двумя таблицами вот так:

SELECT id, name, GROUP_CONCAT(tag_id) FROM person INNER JOIN tag ON person.id = tag.person_id GROUP BY person.id;
+----+------+----------------------+
| id | name | GROUP_CONCAT(tag_id) |
+----+------+----------------------+
|  1 | Bob  | 1,2                  |
|  2 | Jill | 2,3                  |
+----+------+----------------------+

Как я могу превратить это, который, поскольку он использует строку, рассматривается как логический эквивалент (1 = X) И (2 = X) ...

SELECT name, GROUP_CONCAT(tag.tag_id) FROM person LEFT JOIN tag ON person.id = tag.person_id 
GROUP BY person.id HAVING ( ( 1 IN (GROUP_CONCAT(tag.tag_id) ) ) AND ( 2 IN (GROUP_CONCAT(tag.tag_id) ) ) );
Empty set (0.01 sec)

... во что-то, где результат GROUP_CONCAT обрабатывается как список, так что для Боба он будет эквивалентен:

SELECT name, GROUP_CONCAT(tag.tag_id) FROM person INNER JOIN tag ON person.id = tag.person_id AND person.id = 1 
GROUP BY person.id HAVING ( ( 1 IN (1,2) ) AND ( 2 IN (1,2) ) );
+------+--------------------------+
| name | GROUP_CONCAT(tag.tag_id) |
+------+--------------------------+
| Bob  | 1,2                      |
+------+--------------------------+
1 row in set (0.00 sec)

... а для Джилл это будет эквивалентно:

SELECT name, GROUP_CONCAT(tag.tag_id) FROM person INNER JOIN tag ON person.id = tag.person_id AND person.id = 2 
GROUP BY person.id HAVING ( ( 1 IN (2,3) ) AND ( 2 IN (2,3) ) );
Empty set (0.00 sec)

... итоговым результатом будет исключительное условие поиска, требующее, чтобы все перечисленные теги не использовали HAVING COUNT (DISTINCT ...)?

(примечание: эта логика работает без AND, применяя к первому символу строки. Например,

SELECT name, GROUP_CONCAT(tag.tag_id) FROM person LEFT JOIN tag ON person.id = tag.person_id 
  GROUP BY person.id HAVING ( ( 2 IN (GROUP_CONCAT(tag.tag_id) ) ) );
+------+--------------------------+
| name | GROUP_CONCAT(tag.tag_id) |
+------+--------------------------+
| Jill | 2,3                      |
+------+--------------------------+
1 row in set (0.00 sec)
 Treffynnon03 мар. 2011 г., 17:12
Это хорошо, но стоит отметить, что вам не нужно делатьGROUP_CONCAT() во всехFIND_IN_SET(), Вы можете простоSELECT GROUP_CONCAT(tag.tag_id) AS tags_list а потомHAVING FIND_IN_SET(20, tags_list)

Ответы на вопрос(2)

Решение Вопроса

IN(), будет использоватьFIND_IN_SET() тоже вариант?

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set

mysql> SELECT FIND_IN_SET('b','a,b,c,d');
    -> 2

Вот полный пример, основанный на примере проблемы в вопросе, подтвержденный как проверенный спрашивающим в более раннем редактировании вопроса:

SELECT name FROM person LEFT JOIN tag ON person.id = tag.person_id GROUP BY person.id 
  HAVING ( FIND_IN_SET(1, GROUP_CONCAT(tag.tag_id)) ) AND ( FIND_IN_SET(2, GROUP_CONCAT(tag.tag_id)) );
+------+
| name |
+------+
| Bob  |
+------+
 Gia Duong Duc Minh06 дек. 2012 г., 04:07
Спасибо! Мне это тоже нужно.
 user56845809 сент. 2016 г., 12:17
Отлично! Один совет: не забывайте, что, поскольку это похоже на вызов функции, должно бытьнет пробела перед открывающей скобкой / круглыми скобками, иначе вы получите ошибкуFunction dbname.FIND_IN_SET does not exist.
 Wolph17 янв. 2017 г., 23:25
@ AndrésMongeMoreno: в Mysql 5.0 (которая была последней версией в то время, когда я отвечал на этот вопрос) вариантов не так много. В текущем выпуске я бы, вероятно, предложил использовать вместо этого функции JSON:dev.mysql.com/doc/refman/5.7/en/json-functions.html
 Andrés Monge Moreno17 янв. 2017 г., 02:40
Что ж, это решение, но я обнаружил, что FIND_IN_SET чрезвычайно менее эффективен, чем IN ... знаете, есть ли способ действительно достичь того, о чем говорится в вопросе, способ разбить строку на массивоподобную переменную ?
 Andrés Monge Moreno18 янв. 2017 г., 06:20
@ Вольф, я понимаю, нет проблем = D. Просто хотел что-то оставить для будущих читателей. По моему опыту, FIND_IN_SET ЧРЕЗВЫЧАЙНО менее производительный, чем любой другой выбор (даже цикл с курсором на результатах до группировки по).

используя разделитель, и разбить ее в функции, которая будет работать с результатами.

Для тривиального примера, если у вас есть строковый массив, подобный этому: 'one | two | tree | four | five', и вы хотите знать, есть ли два в массиве, вы можете сделать это следующим образом:

create function str_in_array( split_index varchar(10), arr_str varchar(200), compares varchar(20) )
  returns boolean
  begin
  declare resp boolean default 0;
  declare arr_data varchar(20);

  -- While the string is not empty
  while( length( arr_str ) > 0  ) do

  -- if the split index is in the string
  if( locate( split_index, arr_str ) ) then

      -- get the last data in the string
    set arr_data = ( select substring_index(arr_str, split_index, -1) );

    -- remove the last data in the string
    set arr_str = ( select
      replace(arr_str,
        concat(split_index,
          substring_index(arr_str, split_index, -1)
        )
      ,'')
    );
  --  if the split index is not in the string
  else
    -- get the unique data in the string
    set arr_data = arr_str;
    -- empties the string
    set arr_str = '';
  end if;

  -- in this trivial example, it returns if a string is in the array
  if arr_data = compares then
    set resp = 1;
  end if;

 end while;

return ,resp;
end
|

delimiter ;

Я хочу создать набор полезных функций mysql для работы с этим методом. Кто-нибудь заинтересован, пожалуйста, свяжитесь со мной.

Для большего количества примеров, посетитеhttp://blog.idealmind.com.br/mysql/how-to-use-string-as-array-in-mysql-and-work-with/

Ваш ответ на вопрос