En MySQL, je veux pouvoir rechercher '31 - 7'
, quand une autre valeur = '7 - 31'
. Quelle est la syntaxe que je voudrais utiliser pour séparer les chaînes dans MySQL? En PHP, j'utiliserais probablement explode(' - ',$string)
et les mettrais ensemble. Y a-t-il un moyen de faire cela dans MySQL?
Contexte: Je travaille avec des scores sportifs et je veux essayer des jeux où les scores sont identiques (et à la même date). Le score indiqué pour chaque équipe est comparé à celui de la base de données de son adversaire.
L'appel MySQL idéal serait:
Where opponent1.date = opponent2.date
AND opponent1.score = opponent2.score
(opponent2.score
devrait être opponent1.score
en arrière).
MYSQL n’a pas de fonction explode()
comme intégrée. Mais vous pouvez facilement ajouter une fonction similaire à votre base de données et l’utiliser ensuite à partir de requêtes php. Cette fonction ressemblera à:
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, '');
Usage:
SELECT SPLIT_STRING('Apple, pear, melon', ',', 1)
L'exemple ci-dessus retournera Apple
. Je pense qu'il sera impossible de retourner un tableau dans MySQL, vous devez donc spécifier quelle occurrence retourner explicitement dans pos
. Faites-moi savoir si vous réussissez à l'utiliser.
J'essaie avec 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'
voir plus sur mysql.com http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_substring-index
Vous pouvez utiliser une procédure stockée de cette façon.
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 ;
exemple d'appel:
SET @str = "The quick brown fox jumped over the lazy dog";
SET @delim = " ";
CALL explode(@delim,@str);
SELECT id,Word FROM temp_explode;
Tout d’abord, vous devriez changer la structure de la base de données - le score dans ce cas est une sorte de valeur composite et devrait être stocké dans deux colonnes, par exemple. score_Host
, score_guest
.
MySQL ne fournit pas l'équivalent de explode()
mais dans ce cas, vous pouvez utiliser SUBSTRING()
et LOCATE()
pour couper le score d'un hôte et d'un invité.
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()
est utilisé pour convertir une chaîne "23"
en nombre 23
.
Utilisez cette fonction. Il fonctionne comme un charme. remplacer "|" avec le caractère à décomposer/scinder et les valeurs 1, 2, 3, etc. sont basés sur le nombre d’entrées dans le fichier: 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
J'espère que ça aide.
Comme @ arman-p l'a fait remarquer, MYSQL n'a pas d'explode (). Cependant, je pense que la solution présentée est beaucoup plus compliquée que nécessaire. Pour effectuer une vérification rapide lorsque vous recevez une chaîne de liste délimitée par des virgules (par exemple, la liste des clés de table à rechercher), procédez comme suit:
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))
Cela suppose que vous ayez également besoin de vérifier field_3 sur la table. Si vous n'en avez pas besoin, n'ajoutez pas cette condition.
utilisez substring_index, dans l'exemple ci-dessous, j'ai créé un tableau avec la colonne score1 et score2, score1 ayant un score de 3-7, score2 de 7 à 3, etc. comme indiqué dans l'image. La requête ci-dessous peut se scinder en utilisant "-", inverser l'ordre de score2 et comparer à 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
si explos est utilisé avec foreach pour construire une nouvelle chaîne, vous pouvez simuler exploser en utilisant une boucle while comme ceci:
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
cet exemple renverra une liste HTML des pièces. (il faut ajouter des jambes variables requises)
J'ai rencontré le même problème aujourd'hui et je l'ai résolu comme suit: veuillez noter que dans mon cas, je connais le nombre d'éléments contenus dans la chaîne concaténée. Je peux donc les récupérer de cette manière:
set @var1=0;
set @var2=0;
SELECT SUBSTRING_INDEX('value1,value2', ',', 1) into @var1;
SELECT SUBSTRING_INDEX('value1,value2', ',', -1) into @var2;
les variables @ var1 et @ var2 auraient les mêmes valeurs que explode ().