The Power of Oracle SQL

?v=1
Прочитав сегодняшний топик «SQL. Занимательные задачки», я вспомнил, что давно хотел порекомендовать отличную книгу для продвинутого уровня Oracle SQL от нашего отличного специалиста по Oracle, Алекса Репринцева — «The Power of Oracle SQL». Мало того, что она сама по себе чрезвычайно полезная для тех, кто хочет знать Oracle SQL на высоком уровне, так она еще и бесплатная! Кроме того, есть версии и на русском, и на английском.
В общем, ссылки на саму книгу:
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/

© Habrahabr.ru