如何在MySQL存储过程中拆分逗号分隔文本(ID列表)以在SQL“IN”语句中使用结果。
SELECT * FROM table WHERE table.id IN (splitStringFunction(commaSeparatedData, ','));
答案 0 :(得分:40)
这对MySQL来说很简单:
SELECT * FROM table WHERE FIND_IN_SET(table.id, commaSeparatedData);
参考:http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set
答案 1 :(得分:5)
你可以用两种方式做到:
答案 2 :(得分:5)
您可以在存储过程中使用预准备语句来实现此目的。您可以将整个选择查询创建为变量内的字符串,然后将逗号分隔的字符串连接到其IN子句中。然后,您可以从查询字符串变量中生成预准备语句并执行它。
DELIMITER ;;
create procedure testProc(in listString varchar(255))
BEGIN
set @query = concat('select * from testTable where id in (',listString,');');
prepare sql_query from @query;
execute sql_query;
END
;;
DELIMITER ;
call testProc("1,2,3");
答案 3 :(得分:4)
你可以尝试这个MySql示例。在使用它之前,在那里放一些类型安全检查(即check id是整数,或者在插入之前与正则表达式匹配)。
# BEGIN split statements ids
DECLARE current_pos INT DEFAULT 1;
DECLARE delim CHAR DEFAULT ',';
DECLARE current CHAR DEFAULT '';
DECLARE current_id VARCHAR(100) DEFAULT '';;
CREATE TEMPORARY TABLE ids (`id` VARCHAR(100));
split_ids: LOOP
SET current = MID(statement_ids, current_pos, 1);
IF (current_pos = LENGTH(statement_ids)) THEN
IF current != delim THEN SET current_id = CONCAT(current_id,current); END IF;
INSERT INTO ids(id) VALUES (current_id);
LEAVE split_ids;
END IF;
IF current = delim THEN
INSERT INTO ids(id) VALUES (current_id);
SET current_id = '';
ELSE
SET current_id = CONCAT(current_id,current);
END IF;
SET current_pos = current_pos+1;
END LOOP split_ids;
# END split statement ids
# to check ids are correct
SELECT * FROM ids;
# to use the ids:
SELECT * FROM statements WHERE id IN (SELECT id FROM ids);
答案 4 :(得分:2)
好吧,对于像我这样的人来说,稍微“简单”但不那么令人讨厌:
说你有一个表'combined_city_state'看起来像:
'Chicago, Illinois'
将其复制到另外两个表中:
CREATE TABLE city LIKE combined_city_state;
INSERT city SELECT * FROM combined_city_state;
CREATE TABLE state LIKE combined_city_state;
INSERT state SELECT * FROM combined_city_state;
您现在有3个表与'combined_city_state'具有相同的数据。
安装此功能:
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
然后将其应用于每个表以删除额外的数据索引:
UPDATE firms
SET city = (SELECT SPLIT_STR((city), ',', 1));
UPDATE firms
SET state = (SELECT SPLIT_STR((state), ',', 2));
这将为您留下一列只有城市,只有一个州。如果您不再需要,现在可以删除原始的'combined_city_state'列。
答案 5 :(得分:1)
我很惊讶这里没有正确提到单线:
SELECT * FROM table
WHERE id in (SELECT convert(int,Value) FROM dbo.Split(@list_string,',')
你所需要的只是一个Split SQL function,就像下面的那个一样,它也会以其他方式派上用场:
CREATE FUNCTION dbo.Split
(
@List nvarchar(2000),
@SplitOn nvarchar(5)
)
RETURNS @RtnValue table
(
Id int identity(1,1),
Value nvarchar(100)
)
AS
BEGIN
While (Charindex(@SplitOn,@List)>0)
Begin
Insert Into @RtnValue (value)
Select
Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1)))
Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List))
End
Insert Into @RtnValue (Value)
Select Value = ltrim(rtrim(@List))
Return
END
答案 6 :(得分:0)
我已经用连字符解析了数据。下面的示例使用固定的文本字符串来演示,只需更改表中相关列名的引用。我玩了很长时间以确保它能够处理具有不同数量组件的代码,并最终决定添加where子句。您尝试解析的大多数数据都有固定数量的列。
select
SUBSTRING_INDEX(TS,"-",1) as "1",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",2)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",2)))-1)) as "2",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",3)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",3)))-1)) as "3",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",4)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",4)))-1)) as "4",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",5)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",5)))-1)) as "5",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",6)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",6)))-1)) as "6",reverse(left(reverse(SUBSTRING_INDEX(TS,"-",7)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",7)))-1)) as "7",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",8)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",8)))-1)) as "8",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",9)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",9)))-1)) as "9",
reverse(left(reverse(SUBSTRING_INDEX(TS,"-",10)),locate("-",reverse(SUBSTRING_INDEX(TS,"-",10)))-1)) as "10"
from (select "aaa-bbb-ccc-ddd-eee-fff-ggg-hhh-iii-jjj" as TS) as S
where (LENGTH(TS)-LENGTH(REPLACE(TS,'-',''))) =9
答案 7 :(得分:0)
有些奇怪,但是:
SET @i = 1;
set @str = 'a,b,c,d,e,f,g,h';
select temp.length into @length from
(select
ROUND(
(
LENGTH(dt.data)
- LENGTH( REPLACE (dt.data, ",", "") )
) / LENGTH(",")
)+1 AS length
from (select @str as data) dt
) temp;
SET @query = CONCAT('select substring_index(
substring_index(@str, '','', seq),
'','',
-1
) as letter from seq_', @i, '_to_',@length);
PREPARE q FROM @query;
EXECUTE q;
答案 8 :(得分:0)
您可以使用find_in_set()
函数进行收集过滤器
how-to-split-and-search-in-comma-separated-values-in-mysql
SELECT * FROM table WHERE find_in_set(table.id,commaSeparatedData) > 0;