Аналог рекурсии |
|||||||||||||||||||||||||||||||||
Рассмотрим простой пример, который генерирует последовательность Фибоначчи (в последовательности Фибоначчи каждый член равен сумме двух предыдущих, а первые 2 равны единице):
Данный запрос генерирует 18 чисел Фибоначчи, не считая первых двух:
Разберём теперь как оно работает. В строчках 5) 6) генерируется 9 записей. Тут ничего необычного. В строчке 7) мы объявляем две переменные @I, @J и присваиваем им 1. В строке 3) происходит следующее: сначала переменной @I присваивается сумма двух переменных. Затем то же самое присваиваем переменной @J, причем с учетом того, что значение @I уже поменялось. Другими словами, вычисления в SELECT выполняются слева направо – см. также замечание в начале статьи. Причем изменение переменных осуществляется в каждой из наших 9 записей, т.е. при обработке каждой новой строки в переменных @I и @J будут содержаться значения, вычисленные при обработке предыдущей строки. Чтобы решить эту же задачу средствами других СУБД, нам пришлось бы писать рекурсивный запрос!
Примечание:
Переменные нужно объявлять в отдельном подзапросе (строка 7), если бы мы объявили переменную в предложении SELECT, она, скорее всего, вычислилась бы только 1 раз (хотя конкретное поведение будет зависеть от версии сервера). Тип переменной определяется значением, которым она инициализирована. Этот тип может динамически меняться. Если переменной присвоить NULL, её типом будет BLOB. Порядок обработки строк в SELECT, как было сказано выше, зависит от пользовательской сортировки. Простой пример нумерации строк в заданном порядке:
|