web-dev-qa-db-fra.com

Mysql peut-il fractionner une colonne?

J'ai une colonne qui contient des données séparées par des virgules:

1,2,3
3,2,1
4,5,6
5,5,5

J'essaie de lancer une recherche qui interrogerait chaque valeur de la chaîne CSV individuellement.

0<first<5   and  1<second<3  and  2<third<4 

Je comprends que je pourrais renvoyer toutes les requêtes et les scinder moi-même et les comparer moi-même. Je suis curieux de savoir s'il existe un moyen de le faire, alors mysql effectue ce traitement. Merci!

56
ZA.

Utilisation

substring_index(`column`,',',1) ==> first value
substring_index(substring_index(`column`,',',-2),',',1)=> second value
substring_index(substring_index(`column`,',',-1),',',1)=> third value

dans votre clause where.

SELECT * FROM `table`
WHERE 
substring_index(`column`,',',1)<0 
AND
substring_index(`column`,',',1)>5
49
raj karthy

Cela semble fonctionner:

substring_index ( substring_index ( context,',',1 ), ',', -1) ) 
substring_index ( substring_index ( context,',',2 ), ',', -1) ) 
substring_index ( substring_index ( context,',',3 ), ',', -1) ) 
substring_index ( substring_index ( context,',',4 ), ',', -1) )

cela signifie 1ère valeur, 2ème, 3ème, etc.

Explication:

Le substring_index Interne renvoie les n premières valeurs séparées par une virgule. Donc, si votre chaîne d'origine est "34,7,23,89", substring_index( context,',', 3) renvoie "34,7,23".
Le substring_index Externe prend la valeur renvoyée par le substring_index Interne et le -1 Vous permet de prendre la dernière valeur. Donc, vous obtenez "23" du "34,7,23".
Au lieu de -1 Si vous spécifiez -2, Vous obtenez "7,23", car il prend les deux dernières valeurs.

Exemple:

select * from MyTable where substring_index(substring_index(prices,',',1),',',-1)=3382;

Ici, prices est le nom d'une colonne dans MyTable.

21
Oleksiy Muzalyev

Généralement, substring_index fait ce que vous voulez:

mysql> select substring_index("[email protected]","@",-1);
+-----------------------------------------+
| substring_index("[email protected]","@",-1) |
+-----------------------------------------+
| gmail.com                               |
+-----------------------------------------+
1 row in set (0.00 sec)
7
runixo

Vous pouvez obtenir ce que vous voulez en utilisant MySQL REGEXP ou LIKE.

Voir le MySQL Docs on Pattern Matching

4
Damo

Voici une autre variante que j'ai posté sur une question connexe. La vérification de REGEX pour voir si vous êtes hors limites est utile, donc pour une colonne de table, vous la placeriez dans la clause where.

SET @Array = 'one,two,three,four';
SET @ArrayIndex = 2;
SELECT CASE 
    WHEN @Array REGEXP CONCAT('((,).*){',@ArrayIndex,'}') 
    THEN SUBSTRING_INDEX(SUBSTRING_INDEX(@Array,',',@ArrayIndex+1),',',-1) 
    ELSE NULL
END AS Result;
  • SUBSTRING_INDEX(string, delim, n) renvoie le premier n
  • SUBSTRING_INDEX(string, delim, -1) renvoie le dernier seulement
  • REGEXP '((delim).*){n}' vérifie s'il y a n délimiteurs (c'est-à-dire que vous êtes dans les limites)
1
KCD

En addendum à ceci, j'ai des chaînes de la forme: Quelques mots 303

où je voudrais séparer la partie numérique de la queue de la chaîne. Cela semble indiquer une solution possible:

http://lists.mysql.com/mysql/222421

Cependant, le problème est que vous n'obtenez que la réponse "oui, cela correspond" et non l'index de départ de la correspondance de l'expression rationnelle.

1
Merijn Vogel

Ça marche..

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(col,'1', 1), '2', 1), '3', 1), '4', 1), '5', 1), '6', 1)
, '7', 1), '8', 1), '9', 1), '0', 1) as new_col  
FROM table_name group by new_col; 
0
user2257559