如何在MySQL存储过程中拆分逗号分隔文本(ID列表),以便在SQL“IN”语句中使用结果。如何在MySQL存储过程中拆分逗号分隔的文本
SELECT * FROM table WHERE table.id IN (splitStringFunction(commaSeparatedData, ','));
如何在MySQL存储过程中拆分逗号分隔文本(ID列表),以便在SQL“IN”语句中使用结果。如何在MySQL存储过程中拆分逗号分隔的文本
SELECT * FROM table WHERE table.id IN (splitStringFunction(commaSeparatedData, ','));
你可以做到这一点有两种方式:
你可以试试这个MySQL实例。在使用它之前,在其中加入一些类型安全检查(即检查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);
OK,略显 “容易”,但不太令人讨厌的人喜欢我的方式:
说你有一个表 'combined_city_state' 它看起来像:
'Chicago, Illinois'
复制到其他2表格:
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'列。
您可以使用存储过程内的预处理语句来实现此目的。您可以将整个选择查询创建为变量内的字符串,然后将逗号分隔的字符串连接到其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");
我已经用连字符解析了数据。下面的示例使用固定的文本字符串来演示,只需更改表中相关列名称的引用即可。我玩了很长时间,以确保它能够处理具有不同数量组件的代码,并最终决定添加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
我很惊讶这一个班轮不能正常这里提到:
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
这是MSSQL T-SQL,不是MySQL – joezen777 2017-06-12 18:48:51
这是简单得要命的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
哇。那正是我期待的!谢谢。这应该是我认为的正确答案。 – 2014-04-16 12:43:11
@JimmyKane是的,我也是这样想的,但可悲的是已经有一个正确的答案:) – DarkSide 2014-04-16 14:57:38
@Peter Stegnar你应该考虑改变最好的答案。 – 2016-05-02 16:31:30
好的,你能更具体吗? – 2010-02-02 08:43:07
但与正则表达式的想法是伟大的 – 2010-02-02 08:49:53
根据链接只有答案是不好的做法。我知道这是旧的,但仍想留下这个评论,希望你能回来并改进这个答案。特别是考虑到在这两个环节之后并没有立即说明如何将这个问题应用到问题中,所以他们甚至不是真正的非常好的链接来自己回答问题。 (仅讨论链接的答案见http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) – Chris 2016-02-26 13:00:31