从MySQL中的字段中选择多个子字符串

时间:2015-05-14 18:10:00

标签: mysql sql string

我在MySQL中有一个longtext字段。我正在寻找任何媒体'可能在其中,+ / - 〜10个字符的上下文。单行中通常有多个实例。字段,所以我需要看到上下文。如何编写查询来执行此操作?我甚至无法想到从哪里开始。

所以我正在看的是:

SELECT field_data_body FROM table WHERE field_data_body LIKE '%media%';
+----------------------------------+
| field_data_body                  |
+----------------------------------+
| ... ode__media_or ... e immediat | 
+----------------------------------+

该字段实际上是一个长字符串,我只是解析了实际的测试值,以显示与WHERE子句匹配的子字符串。

我真正想要看到的是字符串media的所有实例,在上面的示例中是两个,但在其他字段中可能更多。 SUBSTR仅显示media的第一个实例。

3 个答案:

答案 0 :(得分:1)

在mysql中,你可以为wordcount创建一个用户定义函数。您可以从此UDF获得帮助。

mysql count word in sql syntax

答案 1 :(得分:1)

CREATE FUNCTION你自己的。在函数内部,您可以使用WHILE语句和一般字符串函数,例如LOCATESUBSTRING

这是一个让你入门的例子:

DELIMITER $$

CREATE FUNCTION substring_list(
    haystack TEXT,
    needle VARCHAR(100)
)
RETURNS TEXT
DETERMINISTIC
BEGIN
    DECLARE needle_len INT DEFAULT CHAR_LENGTH(needle);
    DECLARE output_str TEXT DEFAULT '';
    DECLARE needle_pos INT DEFAULT LOCATE(needle, haystack);
    WHILE needle_pos > 0 DO
        SET output_str = CONCAT(output_str, SUBSTRING(haystack, GREATEST(needle_pos - 10, 1), LEAST(needle_pos - 1, 10) + needle_len + 10), '\n');
        SET needle_pos = LOCATE(needle, haystack, needle_pos + needle_len);
    END WHILE;
    RETURN output_str;
END$$

DELIMITER ;

以下是一些测试。对于每个匹配,返回术语(“媒体”)和两侧最多10个字符,所有字符串联在一个字符串中:

SELECT substring_list('1234567890media12345678immediate34567890media1234567890', 'media');
+---------------------------+
| 1234567890media12345678im |
| 12345678immediate34567890 |
| te34567890media1234567890 |
+---------------------------+
SELECT substring_list('0media12345678immediate34567890media1', 'media');
+---------------------------+
| 0media12345678im          |
| 12345678immediate34567890 |
| te34567890media1          |
+---------------------------+

答案 2 :(得分:0)

这是一个使用PHP的解决方案,它将返回每一行和每个结果以及多维数组中的周围字符。

$value = "media";
$surroundingChars = 5;
$strlen = strlen($value);

$stmt = $pdo->prepare("SELECT field_data_body FROM table WHERE field_data_body LIKE ?";
$stmt->execute([ '%'.$value.'%' ]);
$result = 0;
while ($body = $stmt->fetchColumn()) {
    $start = 0;
    while (($pos = stripos($body, $value, $start)) !== FALSE) {
         $return[$result][] = substr($body, $pos - $surroundingChars, $strlen + ($surroundingChars * 2));
         // Adjust next start 
         $start = $pos + $strlen;
    }
    $result++;
}

您可以随时更改$return[$result][]行,但要以您希望的格式回显所有行,您可以这样做:

foreach($return as $row) {
    echo implode('..', $row);
}

正如您在评论中所说,您宁愿查询,但如果您改变主意,这里有一个符合您的PHP要求的解决方案。