SQL: вложенные операторы
Всем привет!
Кому-то данный очерк покажется банальным и бесполезным, но, как показала практика, не все знают про этот, казалось бы, очевидный “лайфхак” — то, что результат работы одних операторов может быть операндом другого оператора.
Сложно и непонятно? Сейчас поясню на примере.
Вот, допустим, у нас есть массив однотипных строк. И нам нужно вырезать из каждой строки часть от одного символа до другого символа.
Что нам для этого надо сделать? Найти 2 значения, которые будут вычисляться динамически, на ходу, и будут уникальны для каждой отдельной строки в массиве.
Итого нам понадобится 2 команды — на вырезание подстроки и на определение позиции определённого символа.
Например, есть у нас строковое значение “quality-lab@mail.ru”. Из него будем вырезать часть, находящуюся между дефисом и @ (в нашем случае это будет “lab”).
Давайте начинать с малого: команды вырезания подстроки из строки в MySQL — это substr, и она имеет следующий формат: substr(a, b, c), где
a — строка, из которой вырезаем,
b — позиция, с которой вырезаем,
c — кол-во символов, которое вырезаем.
Дальше нам понадобится команда, которая ищет символ в строке и возвращает его позицию (первого вхождения) — locate. Она пишется так: locate(a,b), где
а — символ, который ищем,
b — строка, в которой ищем.
И этих инструментов нам будет, в принципе, достаточно. Что делаем дальше?
Ну, для начала, будем искать позицию, с которой начнём вырезать(substr) — это будет позиция символа “-”. Вот так будет выглядеть команда поиска позиции дефиса в строке:
locate(‘-‘, ‘quality-lab@mail.ru’),
а вот так:
select substr(‘quality-lab@mail.ru’, locate(‘-‘, ‘quality-lab@mail.ru’)), —
вся команда, вырезающая подстроку с дефиса и до конца (да, вы правильно поняли — substr можно применять и без последнего параметра, тогда будет вырезано всё до конца строки). И вот таким будет результат работы этого запроса: “-lab@mail.ru”
Почему туда попал дефис? Да потому, что мы искали позицию дефиса в строке, а начать вырезать нам нужно не с дефиса, а со следующего за ней символа. В итоге, приходим к следующему:
select substr(‘quality-lab@mail.ru’, locate(‘-‘,’quality-lab@mail.ru’)+1)
Этот запрос у нас возвращает строку без дефиса: “lab@mail.ru”.
Полдела сделано, в принципе.
Едем дальше — теперь нам надо указать, сколько символов мы будем вырезать . Для этого мы будем делать “финт ушами” — из позиции символа “@” будем вычитать позицию символа “-” +1(нам же нужен не сам дефис, а следующий за ним символ). Делается это так:
select locate(‘@’, ‘quality-lab@mail.ru’) — (locate(‘-‘, ‘quality-lab@mail.ru’) + 1)
В результате получаем цифру 3 — это длина текста между дефисом и собакой. Теперь осталось это дело вставить в выражение substr. Получаем на выходе вот такую монструозную штуку:
select substr(‘quality-lab@mail.ru’, locate(‘-‘, ‘quality-lab@mail.ru’) + 1, locate(‘@’, ‘quality-lab@mail.ru’) — (locate(‘-‘, ‘quality-lab@mail.ru’)+1))
Итогом получаем вожделённое “lab”
Страшно? Понимаю, сам испугался. Давайте еще раз по кускам рассмотрим эту дичь:
substr(‘quality-lab@mail.ru’, — говорим, что будем вырезать подстроку из строки
‘quality-lab@mail.ru’;
locate(‘-‘, ‘quality-lab@mail.ru’) + 1, — в качестве параметра “с какого места начнём вырезать” указываем символ, следующий за дефисом;
locate(‘@’, ‘quality-lab@mail.ru’) — (locate(‘-‘, ‘quality-lab@mail.ru’)+1)) — в качестве параметра “сколько символов будем вырезать” указываем разницу в позициях между символом, следующим за дефисом и @.
Вот, в принципе, и всё. Здесь мы рассмотрели на примере, как можно одни операторы использовать внутри других. Надеюсь, материал был полезен).
Если вам стало интересно, что за зверь такой “sql” — приходите к нам на ПОИНТ, я вас научу росчерком пера писать запросы, жонглировать типами данных и вообще повелевать информацией!