use*_*ca8 13 mysql expression list explode
这个问题是从MYSQL连接结果集中在IN()中的where子句中擦除结果吗?
所以,问题的简短版本.如何将GROUP_CONCAT返回的字符串转换为逗号分隔的表达式列表,IN()将其视为要循环的多个项目的列表?
NB MySQL的文档出现来指代"(逗号,分隔,列表)"作为"表达式列表",和有趣上IN()的页面中使用由IN()似乎或多或少在MySQL文档的唯一的页面永远参考表达列表.所以我不确定用于制作数组或临时表的函数是否可以在这里使用.
基于示例的长版本问题:来自这样的2表数据库:
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 |
+----+------+----------------------+
Run Code Online (Sandbox Code Playgroud)
我该怎么转这个,因为它使用一个字符串被视为(1 = X)AND(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)
Run Code Online (Sandbox Code Playgroud)
...将GROUP_CONCAT结果视为列表,以便对Bob来说,它等同于:
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)
Run Code Online (Sandbox Code Playgroud)
......而对于吉尔来说,这相当于:
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)
Run Code Online (Sandbox Code Playgroud)
...所以整体结果将是一个独占搜索条款,要求所有列出的标签不使用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)
Run Code Online (Sandbox Code Playgroud)
Wol*_*lph 38
而不是使用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
Run Code Online (Sandbox Code Playgroud)
这是一个完整的例子,基于问题中的示例问题,在问题的早期编辑中被提问者确认为已经过测试:
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 |
+------+
Run Code Online (Sandbox Code Playgroud)
您可以使用拆分分隔符将字符串作为数组传递,并将其分解为一个函数,该函数将处理结果。
举个简单的例子,如果你有一个这样的字符串数组:'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 ;
Run Code Online (Sandbox Code Playgroud)
我想创建一组有用的 mysql 函数来使用这种方法。有兴趣者请联络我。
更多示例,请访问http://blog.idealmind.com.br/mysql/how-to-use-string-as-array-in-mysql-and-work-with/