Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从MySQL中的列表字符串中获取单个项_Mysql_List_Stored Procedures - Fatal编程技术网

从MySQL中的列表字符串中获取单个项

从MySQL中的列表字符串中获取单个项,mysql,list,stored-procedures,Mysql,List,Stored Procedures,给定以下表示可能列表的字符串,如何在指定索引n 1,2,3,4,5 word1 word2 word3 管道|分隔|列表 此功能的可能原因如下: 从组_CONCAT输出中提取特定元素 从集合列输出中提取特定元素(转换为字符串时) 从包含逗号分隔列表的标准化较差的表中提取特定元素 在迭代过程中使用循环遍历列表,并对列表中的每个元素执行操作 更新完全忘记了子字符串索引-1(由@fthiella和@Kickstart指出),因此更新了下面的示例 通过创建可在线使用的存储函数来解决此问题。存储函数

给定以下表示可能列表的字符串,如何在指定索引
n

  • 1,2,3,4,5
  • word1 word2 word3
  • 管道|分隔|列表
此功能的可能原因如下:

  • 从组_CONCAT输出中提取特定元素
  • 从集合列输出中提取特定元素(转换为字符串时)
  • 从包含逗号分隔列表的标准化较差的表中提取特定元素
  • 在迭代过程中使用循环遍历列表,并对列表中的每个元素执行操作

更新完全忘记了子字符串索引-1(由@fthiella和@Kickstart指出),因此更新了下面的示例

通过创建可在线使用的存储函数来解决此问题。存储函数能够接受输入字符串、任何单个字符分隔符和要提取的所需项的索引

存储函数定义如下

CREATE DEFINER = `user`@`%` 
FUNCTION `getListElement`(
    inString VARCHAR(255) , 
    inDelimiter CHAR(1) , 
    inIndexToReturn TINYINT UNSIGNED
) RETURNS varchar(255) READS SQL DATA DETERMINISTIC SQL SECURITY INVOKER
BEGIN

    -- Takes in as argument a string, and then breaks out the desired string
    DECLARE resultString VARCHAR(255) DEFAULT inString;
    DECLARE numberOfListElements TINYINT UNSIGNED DEFAULT 0;
    DECLARE errorMessage VARCHAR(255) DEFAULT 'Requested index was < 1 which was invalid';

    -- First of all, additional processing only needed for element 2 upwards
    IF inIndexToReturn = 1 THEN

        RETURN SUBSTRING_INDEX( resultString , inDelimiter , inIndexToReturn);

    ELSEIF inIndexToReturn > 1 THEN

        -- Count the number of elements
        -- This will count the missing delimiters based off the replace.  A list of 4 will be missing 3 characters.
        SET numberOfListElements = ( CHAR_LENGTH( resultString ) + 1 ) - CHAR_LENGTH( REPLACE( resultString , inDelimiter , '' ) );

        IF numberOfListElements >= inIndexToReturn THEN

            -- Make sure to only return the last of the elements returend by the first SUBSTRING_INDEX
            RETURN SUBSTRING_INDEX( SUBSTRING_INDEX( inString , inDelimiter , inIndexToReturn ) , inDelimiter , -1 );

        END IF;

        SET errorMessage = CONCAT('List index ',inIndexToReturn,' was requested from a list with ',numberOfListElements,' elements');

    END IF;

    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = errorMessage;

END

重要空格分隔列表似乎会导致此过程出现问题,因此在将字符串解析到函数中之前,我建议执行一个简单的
替换
,用另一个合适的单字符分隔符替换空格(即
|
,具体取决于字符串中的内容)

此函数没有本机函数。可以使用两个子字符串索引函数。您需要检查该特定索引项是否存在:

SET @string:='1,2,3,4,5';
SET @delimiter:=',';
SET @n:=6;

SELECT
  CASE WHEN
    CHAR_LENGTH(@string)-CHAR_LENGTH(REPLACE(@string, @delimiter, ''))>=
    @n*CHAR_LENGTH(@delimiter)-1
  THEN
    SUBSTRING_INDEX(SUBSTRING_INDEX(@string, @delimiter, @n), @delimiter, -1)
  END;
  • SUBSTRING\u索引(@string,@delimiter,@n)
    返回
    @string
    中出现
    @delimiter
    之前的字符串
    @string
    中的子字符串
  • SUBSTRING\u INDEX(…,@delimiter,-1)
    返回最后一个分隔符右侧的所有内容
  • 您需要检查分隔符
    @n
    是否存在。我们可以用分隔符减去字符串的长度,删除分隔符的字符串-使用
    REPLACE(@string,@delimiter')
    -并查看它是否大于
    @n*CHAR\u length(@delimiter)-1

纯SQL操作方法:-

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(somefield, '|', 3), '|', -1)
FROM sometable a
如果不存在第三个元素(例如),则要返回NULL(或其他固定值):-


真的很惊讶这不是某种内置函数tbh,似乎不是一个要解决的奇怪问题。找不到相关的答案,下面是我的应对方法。作为记录,我实际上试图解决的问题是在进一步处理之前从短语中提取成分词。也许其他人比我有更好的选择:)
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(somefield, '|', 3), '|', -1)
FROM sometable a
SELECT IF((LENGTH(somefield) - LENGTH(REPLACE(somefield, '|', '')) + 1) >= 10, SUBSTRING_INDEX(SUBSTRING_INDEX(somefield, '|', 10), '|', -1), NULL)
FROM sometable a