簡體   English   中英

從MySQL中的字段中選擇多個子字符串

[英]Selecting multiple substrings from a field in MySQL

我有一個在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的第一個實例。

在mysql中,您可以為此創建一個用戶定義函數,例如wordcount。 您可以從此UDF獲得幫助。

mysql sql語法中的單詞計數

自己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          |
+---------------------------+

這是使用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要求的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM