Как избежать конкретного символа в MySQL - PullRequest
1 голос
/ 07 мая 2019

У меня есть таблица SQL с генетической информацией (имя гена, функция, цепь ...) Я хочу получить количество хромосом (21, так как я работаю с человеческим геномом). Проблема в том, что некоторые хромосомы «повторяются». Например: SELECT DISTINCT chrom FROM table LIMIT 6;

chr1
chr10
chr10_GL383545v1_alt
chr10_GL383546v1_alt
chr11
chr11_JH159136v1_alt

Как видите, у меня более одного chr10, поэтому, если я посчитаю DISTINCT хромосомы, я получу около 6000.

Я пытался использовать NOT LIKE "_", но не сработало. Я думал, что смогу «форсировать» результат с помощью LIKE "chr1" и так далее, но я чувствую, что меня обманывают, и это не совсем то, что я ищу. Я хотел бы, чтобы избежать каждого "_", но работает SELECT COUNT(DISTINCT chrom) NOT LIKE "_" FROM table; возвращает мне только 1 результат ...

LEFT тоже не оптимально, потому что мне нужно было бы указать длину строки, и я хочу систему, которую я мог бы использовать, ничего не зная об ожидаемом результате. Так что запуск LEFT "", 4 и LEFT "", 5 - это не то, что я ищу. Есть ли способ, которым я могу сосчитать все, что не содержит определенный характер? Есть лучшая стратегия?

Большое спасибо!

Ответы [ 3 ]

3 голосов
/ 07 мая 2019

Подчеркивание само по себе является символом подстановки, поэтому его необходимо экранировать. Кроме того, вы хотите сопоставить любые символы до и после этого символа подчеркивания, поэтому необходимо использовать подстановочный знак % вокруг экранированного подчеркивания.

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

Также вы можете использовать substring_index(), чтобы получить отличную строку перед подчеркиванием и сосчитать их:

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

Хотя это почти наверняка будет медленнее.

0 голосов
/ 07 мая 2019

Проблема с SELECT COUNT(DISTINCT chrom) NOT LIKE "_" FROM table; заключается в расположении сравнения и отсутствии подстановочных знаков % в строке сравнения LIKE.

Любое из следующих действий должно работать для вас:

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

Использование ESACPE и указание escape-символа после LIKE во многих случаях проще, чем использование \, поскольку,в зависимости от вашего сценария, вам может понадобиться двойная комбинация с \.(или если вы пишете это, скажем, php, triple escape)

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

LOCATE() также легче использовать здесь.Но я считаю, что это будет медленнее, чем просто сделать LIKE.Разница в производительности, вероятно, довольно незначительна, поэтому в большинстве случаев это просто предпочтение.

0 голосов
/ 07 мая 2019

Используйте REGEXP, если хотите сохранить простоту. LIKE быстрее, хотя.

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

Я также рекомендую INSTR, который, я думаю, будет работать лучше, чем REGEXP.

SELECT count(chrom) FROM table WHERE INSTR(chrom, '_')=0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...