如何在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