Books and articles about SQL Rambler's Top100 Сменить язык на: Русский 29 March 2024 14:06:04


www.sql-ex.ru
Skip Navigation Links  

 

Print  Версия для печати

На главную страницу

Простые рекурсивные CTE.

Rob Farley (оригинал: Clustered Indexes in Simple recursive CTE)
Перевод Моисеенко С.И.

Я люблю CTE (общие табличные выражения). Главным образом, потому, что они дают мне возможность получить производную таблицу, к которой я могу неоднократно обращаться. Я нечасто использую их рекурсивные возможности. Однако когда я это делаю, то постоянно восхищаюсь мощью таких решений.

Сегодня мне довелось получить чудный способ преобразования целых чисел в их двоичное представление.

Итак, я применяю CTE:

with ctebins as
(select num as num_orig, num as working_level, cast('' as varchar(max)) as binval
from nums_bin
union all
select c.num_orig, c.working_level / 2, cast(c.working_level % 2 as varchar(max)) + c.binval
from ctebins c
where c.working_level > 0
)
select num_orig, binval
from ctebins
where working_level = 0
;

Здесь верхний уровень CTE заполняется пачкой чисел из nums_bin, наряду с пустой строкой. Знаю, что я не должен использовать varchar(max) - нам не нужно так много, в конце концов...

Затем CTE заполняется строками, используя рекурсию. Я сохраняю оригинальное число (чтобы его использовать позже), и продолжаю сокращать его вдвое, чтобы вывести двоичное число. После чего я запрашиваю полный CTE для последнего уровня рекурсии, когда число, с которым я работаю, уменьшилось до нуля.

Это работает прекрасно и очень быстро на большом наборе чисел.

Комментарий от Omnibuzz

Ниже мое решение, использующее СТЕ. Оно определенно не такое заумное, как данное Митчем (опущено - прим. переводчика), но работает прекрасно :-).

Предполагая, что nums_bin - таблица, содержащая 50000 записей, выполним запрос:

declare @maxval int
select @maxval = max(num) from nums_bin;
with cte as
(
select 1 as bin,1 as counter
union all
select bin*2,counter + 1 from cte
where bin*2 < @maxval
)
select num,
(select (num&bin)/bin from cte b order by counter desc for xml path('')) as bin
from nums_bin

20/10/2006

На главную страницу

Print  Версия для печати


Usage of any materials of this site is possible
only under condition of mandatory allocation of the direct link to a site
http://www.sqlbooks.ru
on each page where used materials are placed.

 Main   Articles    Books 
Рейтинг@Mail.ru Rambler's Top100 Alt Упражнения по SQL: обучение, тестирование, сертификация по языку SQL Copyright c 2002-2006. All rights reserved.