sql-等效于explode()以在MySQL中使用字符串
在MySQL中,当另一个值= opponent2.score时,我希望能够搜索'31 - 7'。在MySQL中用于拆分字符串的语法是什么? 在PHP中,我可能会使用opponent1.score并将它们放在一起。 有没有办法在MySQL中做到这一点?
背景:我正在研究体育比分,并且想尝试比分相同(并且在同一日期)的游戏-每个团队列出的分数与对手的数据库记录相比是倒数的。
理想的MySQL调用将是:
Where opponent1.date = opponent2.date
AND opponent1.score = opponent2.score
(opponent2.score需要向后opponent1.score)。
Bob Cavezza asked 2020-07-31T19:34:26Z
11个解决方案
65 votes
MYSQL没有内置类似apple之类的函数。但是您可以轻松地向数据库中添加类似的函数,然后从php查询中使用它。 该函数将如下所示:
CREATE FUNCTION SPLIT_STRING(str VARCHAR(255), delim VARCHAR(12), pos INT)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(str, delim, pos),
LENGTH(SUBSTRING_INDEX(str, delim, pos-1)) + 1),
delim, '');
用法:
SELECT SPLIT_STRING('apple, pear, melon', ',', 1)
上面的示例将返回apple。我认为在MySQL中返回数组将是不可能的,因此您必须在pos中指定要显式返回的事件。让我知道您是否成功使用它。
Arman P. answered 2020-07-31T19:40:06Z
46 votes
我尝试SUBSTRING_INDEX(string,delimiter,count)
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
-> 'www.mysql'
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
-> 'mysql.com'
在mysql.com上查看更多信息[http://dev.mysql.com/doc/refman/5.1/zh-CN/string-functions.html#function_substring-index]
madde74 answered 2020-07-31T19:40:31Z
23 votes
您可以通过这种方式使用存储过程。
DELIMITER |
CREATE PROCEDURE explode( pDelim VARCHAR(32), pStr TEXT)
BEGIN
DROP TABLE IF EXISTS temp_explode;
CREATE TEMPORARY TABLE temp_explode (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, word VARCHAR(40));
SET @sql := CONCAT('INSERT INTO temp_explode (word) VALUES (', REPLACE(QUOTE(pStr), pDelim, '\'), (\''), ')');
PREPARE myStmt FROM @sql;
EXECUTE myStmt;
END |
DELIMITER ;
示例调用:
SET @str = "The quick brown fox jumped over the lazy dog";
SET @delim = " ";
CALL explode(@delim,@str);
SELECT id,word FROM temp_explode;
Disha Goyal answered 2020-07-31T19:40:55Z
17 votes
首先,您应该更改数据库结构-这种情况下的分数是某种复合值,应存储在两列中,例如。 "23"、23。
MySQL不提供等效的"23",但是在这种情况下,您可以使用"23"和"23"降低主机和访客的分数。
SELECT
CONVERT(SUBSTRING(score, 1, LOCATE('-',score) - 2) USING INTEGER) as score_host,
CONVERT(SUBSTRING(score, LOCATE('-',score)+2) USING INTEGER) as score_guest
FROM ...;
"23"用于将字符串"23"转换为数字23。
Crozin answered 2020-07-31T19:41:25Z
6 votes
使用此功能。 它像一种魅力。 替换“ |” 带有要爆炸/拆分的字符,值1,2,3等基于数据集中的条目数:Value_ONE | Value_TWO | Value_THREE。
SUBSTRING_INDEX(SUBSTRING_INDEX(`tblNAME`.`tblFIELD`, '|', 1), '|', -1) AS PSI,
SUBSTRING_INDEX(SUBSTRING_INDEX(`tblNAME`.`tblFIELD`, '|', 2), '|', -1) AS GPM,
SUBSTRING_INDEX(SUBSTRING_INDEX(`tblNAME`.`tblFIELD`, '|', 3), '|', -1) AS LIQUID
我希望这有帮助。
Sergio Rodriguez answered 2020-07-31T19:41:50Z
2 votes
正如@ arman-p指出的那样,MYSQL没有explode()。 但是,我认为提出的解决方案要复杂得多。 要在获得逗号分隔的列表字符串(例如要查找的表键的列表)时进行快速检查,请执行以下操作:
SELECT
table_key, field_1, field_2, field_3
FROM
my_table
WHERE
field_3 = 'my_field_3_value'
AND (comma_list = table_key
OR comma_list LIKE CONCAT(table_key, ',%')
OR comma_list LIKE CONCAT('%,', table_key, ',%')
OR comma_list LIKE CONCAT('%,', table_key))
假设您还需要检查表上的field_3。 如果不需要它,请不要添加该条件。
Al Zziwa answered 2020-07-31T19:42:14Z
2 votes
使用substring_index,在下面的示例中,我创建了一个表,其中包含列score1和score2,score1具有3-7,score2 7-3等,如图中所示。 下面的查询能够使用“-”进行拆分,并反转得分2的顺序并与得分1比较
SELECT CONCAT(
SUBSTRING_INDEX(score1, '-', 1),
SUBSTRING_INDEX(score1,'-',-1)
) AS my_score1,
CONCAT(
SUBSTRING_INDEX(score2, '-', -1),
SUBSTRING_INDEX(score2, '-', 1)
) AS my_score2
FROM test HAVING my_score1=my_score2
philip mudenyo answered 2020-07-31T19:42:35Z
1 votes
如果将explode与foreach一起使用以构建新的字符串,则可以通过使用while循环来模拟爆炸:
CREATE FUNCTION explode_and_loop(sep VARCHAR(),inputstring VARCHAR()) RETURNS VARCHAR()
BEGIN
DECLARE part,returnstring VARCHAR();
DECLARE cnt,partsCnt INT();
SET returnstring = '';
SET partsCnt = ((LENGTH(inputstring ) - LENGTH(REPLACE(inputstring,sep,''))) DIV LENGTH(sep);
SET cnt = 0;
WHILE cnt <= partsCnt DO
SET cnt = cnt + 1;
SET part = SUBSTRING_INDEX(SUBSTRING_INDEX(inputstring ,sep,cnt),sep,-1);
-- DO SOMETHING with the part eg make html:
SET returnstring = CONCAT(returnstring,'
',part,'')END WHILE;
RETURN returnstring;
END
此示例将返回部件的html列表。 (必须添加可变长度)
ohjay answered 2020-07-31T19:46:38Z
0 votes
我今天也遇到了同样的问题,并按以下方式解决了该问题,请注意我的情况,我知道串联字符串中的项目数,因此可以通过以下方式恢复它们:
set @var1=0;
set @var2=0;
SELECT SUBSTRING_INDEX('value1,value2', ',', 1) into @var1;
SELECT SUBSTRING_INDEX('value1,value2', ',', -1) into @var2;
变量@ var1和@ var2的值类似于explode()。
DoubleA answered 2020-07-31T19:47:03Z
0 votes
这实际上是所选答案的修改版本,以支持Unicode字符,但是我没有足够的声誉在此发表评论。
CREATE FUNCTION SPLIT_STRING(str VARCHAR(255) CHARSET utf8, delim VARCHAR(12), pos INT) RETURNS varchar(255) CHARSET utf8
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(str, delim, pos),
CHAR_LENGTH(SUBSTRING_INDEX(str, delim, pos-1)) + 1),
delim, '')
修改如下:
第一个参数设置为CHAR_LENGTH()
该函数设置为返回CHAR_LENGTH()
该代码使用CHAR_LENGTH()而不是LENGTH()来计算字符长度而不是字节长度。
vensires answered 2020-07-31T19:47:40Z
0 votes
我不确定这是否能完全回答问题(不是),但这是我为非常相似的问题想出的解决方案。 我知道其他一些解决方案看起来更短,但是它们似乎比必要的更多地使用了SUBSTRING_INDEX()方法。 在这里,我尝试对每个定界符仅使用一次LOCATE()。
-- *****************************************************************************
-- test_PVreplace
DROP FUNCTION IF EXISTS test_PVreplace;
delimiter //
CREATE FUNCTION test_PVreplace (
str TEXT, -- String to do search'n'replace on
pv TEXT -- Parameter/value pairs 'p1=v1|p2=v2|p3=v3'
)
RETURNS TEXT
-- Replace specific tags with specific values.
sproc:BEGIN
DECLARE idx INT;
DECLARE idx0 INT DEFAULT 1; -- 1-origined, not 0-origined
DECLARE len INT;
DECLARE sPV TEXT;
DECLARE iPV INT;
DECLARE sP TEXT;
DECLARE sV TEXT;
-- P/V string *must* end with a delimiter.
IF (RIGHT (pv, 1) <> '|') THEN
SET pv = CONCAT (pv, '|');
END IF;
-- Find all the P/V pairs.
SELECT LOCATE ('|', pv, idx0) INTO idx;
WHILE (idx > 0) DO
SET len = idx - idx0;
SELECT SUBSTRING(pv, idx0, len) INTO sPV;
-- Found a P/V pair. Break it up.
SELECT LOCATE ('=', sPV) INTO iPV;
IF (iPV = 0) THEN
SET sP = sPV;
SET sV = '';
ELSE
SELECT SUBSTRING(sPV, 1, iPV-1) INTO sP;
SELECT SUBSTRING(sPV, iPV+1) INTO sV;
END IF;
-- Do the substitution(s).
SELECT REPLACE (str, sP, sV) INTO str;
-- Do next P/V pair.
SET idx0 = idx + 1;
SELECT LOCATE ('|', pv, idx0) INTO idx;
END WHILE;
RETURN (str);
END//
delimiter ;
SELECT test_PVreplace ('%one% %two% %three%', '%one%=1|%two%=2|%three%=3');
SELECT test_PVreplace ('%one% %two% %three%', '%one%=I|%two%=II|%three%=III');
SELECT test_PVreplace ('%one% %two% %three% - %one% %two% %three%', '%one%=I|%two%=II|%three%=III');
SELECT test_PVreplace ('%one% %two% %three% - %one% %two% %three%', '');
SELECT test_PVreplace ('%one% %two% %three% - %one% %two% %three%', NULL);
SELECT test_PVreplace ('%one% %two% %three%', '%one%=%two%|%two%=%three%|%three%=III');
Alan Stewart answered 2020-07-31T19:48:01Z