Эквивалент explode () для работы со строками в MySQL - PullRequest
41 голосов
/ 08 мая 2011

В MySQL я хочу иметь возможность искать '31 - 7', когда другое значение = '7 - 31'. Какой синтаксис я бы использовал для разделения строк в MySQL? В PHP я, вероятно, использовал бы explode(' - ',$string) и сложил бы их вместе. Есть ли способ сделать это в MySQL?

Предыстория: я работаю со спортивными результатами и хочу попробовать игры, в которых результаты одинаковы (и также в одну и ту же дату) - указанные результаты для каждой команды в обратном порядке сравниваются с данными из базы данных их противника.

Идеальный вызов MySQL:

Where opponent1.date  = opponent2.date
  AND opponent1.score = opponent2.score

(opponent2.score должно быть opponent1.score в обратном направлении).

Ответы [ 10 ]

63 голосов
/ 08 мая 2011

MYSQL не имеет встроенной функции explode(). Но вы можете легко добавить аналогичную функцию в вашу БД и затем использовать ее из 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.Дайте мне знать, если вам это удастся.

44 голосов
/ 31 января 2014

Я пытаюсь с 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/en/string-functions.html#function_substring-index

23 голосов
/ 02 ноября 2012

Вы можете использовать хранимую процедуру таким образом.

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;
    
17 голосов
/ 08 мая 2011

Прежде всего вы должны изменить структуру базы данных - в этом случае оценка является своего рода составным значением и должна храниться в двух столбцах, например. score_host, score_guest.


MySQL не предоставляет explode() эквивалента, однако в этом случае вы можете использовать SUBSTRING() и LOCATE(), чтобы сократить счет хоста и гостя.

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 ...;

CONVERT() используется для приведения строки "23" в число 23.

5 голосов
/ 02 июля 2015

Используйте эту функцию.Отлично работает.заменить "|"с символом, который нужно взорвать / разделить, а значения 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

Надеюсь, это поможет.

2 голосов
/ 11 июля 2017

используйте substring_index, в приведенном ниже примере я создал таблицу с столбцами Score1 и Score2, Score1 имеет 3-7, Score2 7-3 и т. Д., Как показано на рисунке.Приведенный ниже запрос может быть разделен с помощью «-» и в обратном порядке Score2 и сравнить с Score1

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

scores table

query results

2 голосов
/ 09 сентября 2014

Как отметил @ arman-p, в MYSQL нет функции explode ().Однако я думаю, что решение представлено гораздо сложнее, чем нужно.Чтобы выполнить быструю проверку, когда вам дают строку списка с разделителями-запятыми (например, список ключей таблицы для поиска), вы делаете:тоже.Если вам это не нужно, не добавляйте это условие.

1 голос
/ 05 ноября 2017

если используется разнесение вместе с 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,'<li>',part,'</li>')
    END WHILE;
    RETURN returnstring;
END

, в этом примере будет возвращен список HTML-частей.(обязательные переменные длины должны быть добавлены)

0 голосов
/ 08 апреля 2019

На самом деле это измененная версия выбранного ответа для поддержки символов Юникода, но у меня недостаточно репутации, чтобы комментировать.

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, '')

Изменения следующие:

  • Первый параметр установлен как utf8
  • Функция настроена на возврат utf8
  • Код использует CHAR_LENGTH() вместо LENGTH() для вычисления длина символа и не длина байта .
0 голосов
/ 16 декабря 2015

Я столкнулся с той же проблемой сегодня и решил ее, как показано ниже, обратите внимание, в моем случае, я знаю количество элементов в объединенной строке, поэтому я могу восстановить их следующим образом:

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 ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...