1
votes

Comment éviter un caractère spécifique dans MySQL

J'ai une table SQL, avec des informations génétiques (nom du gène, fonction, brin ...) Je veux récupérer la quantité de chromosomes (21 car je travaille avec le génome humain). Le problème est que certains chromosomes sont "répétés". Par exemple: SELECT DISTINCT chrom FROM table LIMIT 6;

chr1
chr10
chr10_GL383545v1_alt
chr10_GL383546v1_alt
chr11
chr11_JH159136v1_alt

Comme vous pouvez le voir, j'ai plus d'un chr10, donc si je compte le DISTINCT chromosomes Je reçois environ 6000.

J'ai essayé d'utiliser NOT LIKE "_" mais cela n'a pas fonctionné. J'ai pensé que je pourrais "forcer" le résultat avec LIKE "chr1" et ainsi de suite, mais j'ai envie de tricher et ce n'est pas exactement ce que je recherche. Je voudrais un moyen d'éviter tous les "_", mais en cours d'exécution SELECT COUNT (DISTINCT chrom) NOT LIKE "_" FROM table; me renvoie juste 1 résultat ...

LEFT n'est pas non plus optimal, parce que je devrais spécifier la longueur de la chaîne, et, je veux un système que je pourrais utiliser sans rien savoir sur le résultat attendu. Donc exécuter un LEFT "", 4 et LEFT "", 5 n'est pas ce que je recherche. Existe-t-il un moyen de compter tout ce qui ne contient PAS un certain caractère? Il existe une meilleure stratégie?

Merci beaucoup!


2 commentaires

votre question n'est pas claire .. essayez d'ajouter un échantillon de données clair et le résultat attendu ..


Dans un NOT LIKE , vous devez utiliser des caractères génériques % . Comme ceci: PAS COMME "% \ _%" . Voir: 12.5.1 Fonctions de comparaison de chaînes


3 Réponses :


3
votes

Le trait de soulignement est un caractère générique lui-même, il doit donc être échappé. De plus, vous voulez faire correspondre tous les caractères avant et après ce caractère de soulignement, donc le caractère générique % est nécessaire autour du trait de soulignement échappé.

SELECT COUNT(DISTINCT SUBSTRING_INDEX(chrom, '_', 1)) FROM table;

Vous pouvez également utiliser substring_index () pour obtenir une chaîne distincte avant le trait de soulignement et les compter:

SELECT count(chrom) FROM table WHERE chrom NOT LIKE '%\_%`;

Bien que ce soit presque certainement plus lent.


1 commentaires

Bien, cela a fonctionné! Bon point de compter avant de spécifier "ne pas compter", ça me donnait mal à la tête. Merci pour l'explication claire aussi! Juste pour mémoire, il y a quelque chose de bizarre car la première ligne de code que vous donnez me renvoie 26 chromosomes (22 + X + Y + M + Un), mais la deuxième ligne renvoie 25 (comme ci-dessus mais sans Un). Il y a donc une différence entre vos deux solutions, même si les deux fonctionnent très bien. J'utilise l'annotation humaine refGene si quelqu'un est intéressé.



0
votes

Utilisez REGEXP si vous souhaitez rester simple. LIKE est cependant plus rapide.

SELECT count(chrom) FROM table WHERE INSTR(chrom, '_')=0;

Je recommande également INSTR qui, je pense, fonctionnera mieux que REGEXP.

SELECT count(chrom) FROM table WHERE chrom NOT REGEXP '_';


0 commentaires

0
votes

Le problème avec la table SELECT COUNT (DISTINCT chrom) NOT LIKE "_" FROM table; est l'emplacement de la comparaison et l'absence de caractères génériques % dans le LIKE chaîne de comparaison.

L'un ou l'autre des éléments suivants devrait fonctionner pour vous:

SELECT COUNT(DISTINCT chrom) FROM table WHERE LOCATE('_', chrom) > 0;

Utilisation de ESACPE et spécification d'un caractère d'échappement après le code LIKE > est plus facile que d'utiliser \ dans de nombreux cas car, selon votre scénario, vous devrez peut-être vous rappeler de double échapper avec \ . (ou si vous écrivez ceci en php, par exemple, triple escape)

SELECT COUNT(DISTINCT chrom) FROM table WHERE chrom  NOT LIKE '%|_%' ESCAPE '|';

LOCATE () est également plus facile à utiliser ici. Mais je pense que ce serait plus lent que de simplement faire un LIKE . La différence de performance est probablement assez insignifiante, donc dans la plupart des cas, c'est juste une préférence.


2 commentaires

Merci, votre première ligne a donné la réponse tout comme le code de @JNevill. Il semble que "\" n'ait pas besoin d'être supprimé avec ESCAPE , a trouvé cela intéressant.


`est un caractère utilisé pour l'échappement par défaut. ESCAPE` ne doit être utilisé que si vous souhaitez utiliser un caractère autre que `pour échapper. Ceci est utile dans les scénarios, comme l'utilisation d'un LIKE` de php, où vous auriez autrement besoin de doubler ou tripler l'échappement si vous deviez utiliser ``