The Power of Oracle SQL
Прочитав сегодняшний топик «SQL. Занимательные задачки», я вспомнил, что давно хотел порекомендовать отличную книгу для продвинутого уровня Oracle SQL от нашего отличного специалиста по Oracle, Алекса Репринцева — «The Power of Oracle SQL». Мало того, что она сама по себе чрезвычайно полезная для тех, кто хочет знать Oracle SQL на высоком уровне, так она еще и бесплатная! Кроме того, есть версии и на русском, и на английском.
В общем, ссылки на саму книгу:
https://sqlmdx.net/2011/03/15/tpoos/
В общем, ссылки на саму книгу:
https://sqlmdx.net/2011/03/15/tpoos/
И на обсуждение самой книги с автором:
https://www.sql.ru/forum/1248365/the-power-of-oracle-sql
И для затравки пара примеров задач из нее:
- Connected components
имеется неориентированный (ненаправленный) граф, заданный списком ребер и
требуется получить компоненты связности.
Для данных из таблицы нижеcreate table edge(x1, x2) as select 10,20 from dual union all select 50,40 from dual union all select 20,30 from dual union all select 20,40 from dual union all select 60,70 from dual union all select 80,60 from dual union all select 20,90 from dual;
Ожидается следующий результат (порядок нумерации компонент не критичен)X GRP --- ----- 10 1 20 1 30 1 40 1 50 1 60 2 70 2 80 2 90 1
- Ordering dependencies
Теперь рассмотрим задачу на ориентированном (направленном) графе.
Есть таблица с зависимостями между объектами, не содержащая циклических
зависимостей. Однако между парами вершин может существовать более одного пути, поэтому
такую структуру нельзя назвать деревом.create table d(name, referenced_name) as (select null, 'a' from dual union all select null, 'd' from dual union all select 'a', 'b' from dual union all select 'd', 'b' from dual union all select 'b', 'e' from dual union all select 'b', 'c' from dual union all select 'e', 'c' from dual);
Необходимо обойти все объекты за минимальное число шагов, при этом на каждом шаге
можно обходить только те объекты, для которых обойдены все зависимые объекты. То есть, на
первом шаге обходятся объекты не имеющие зависимостей, на втором шаге те, которые зависят
от объектов первого шага и так далее. Иными словами нумеруются зависимости по глубине. - Covering ranges
Предположим есть таблица следующего видаcreate table t_range(a, b) as (select 1, 15 from dual union all select 3, 17 from dual union all select 6, 19 from dual union all select 10, 21 from dual union all select 17, 26 from dual union all select 18, 29 from dual union all select 20, 32 from dual union all select 24, 35 from dual union all select 28, 45 from dual union all select 30, 49 from dual);
b > a для каждой пары a, b; a уникально
Необходимо получить отрезки (1:15), (17:26), (28:45), то есть начинаем со строки с
минимальным a, и следующую строку берем такую, что для нее a больше b из текущей строки и так
далее. - Top paths
Для таблицы со списком директорий в файловой системы вывести только те, что не имеют
поддиректорий.create table t_path(path) as select '/tmp/cat/' from dual union all select '/tmp/cata/' from dual union all select '/tmp/catb/' from dual union all select '/tmp/catb/catx/' from dual union all select '/usr/local/' from dual union all select '/usr/local/lib/liba/' from dual union all select '/usr/local/lib/libx/' from dual union all select '/var/cache/' from dual union all select '/var/cache/'||'xyz'||rownum||'/' from dual connect by level <= 1e6;
Для указанных данных результатом будетPATH ------------------------------------------------------- /tmp/cat/ /tmp/cata/ /tmp/catb/ /usr/local/ /var/cache/