Повторите значение столбца для нескольких записей с разными идентификаторами в Oracle.

Я использую Oracle 12c.

У меня есть иерархическая таблица Oracle, в которой я хотел бы использовать короткое имя родительского узла (например, start with parent_node_is is null) для всех дочерних узлов, принадлежащих этому родителю.

Например: Имя таблицы: nodes_tab

NODE_ID    SHORT_NAME     PARENT_NODE_ID
---------- -------------- --------------
1          Parent Node-1  NULL
2          Child Node-2   1
3          Child Node-3   1
4          Child Node-4   2
5          Child Node-5   2
6          Child Node-6   4
7          Child Node-7   6

Чего я хотел бы добиться, так это запросить вышеуказанную вкладку nodes_tab для всех node_ids, но назначить short_name, принадлежащий родительскому узлу.

В идеале я просто хочу повторить одно и то же имя Parent Node-1 для остальных node_id от 2 до 7, но не знаю, каким должен быть SQL-запрос. Я посмотрел на LAG, но, похоже, он не помогает.

Результат, который мне нужен:

NODE_ID    SHORT_NAME   
---------- -------------
1          Parent Node-1
2          Parent Node-1
3          Parent Node-1
4          Parent Node-1
5          Parent Node-1
6          Parent Node-1
7          Parent Node-1

Вы ищете CONNECT_BY_ROOT(short_name)? См. этот вопрос: stackoverflow.com/questions/15595850/…

default locale 22.05.2019 11:24

То, что я ищу, - это просто запрос, который использует короткое имя строки, где parent_node_id is NULL, и повторяет это короткое имя для всех других записей, где parent_node_id is NOT NULL

tonyf 22.05.2019 11:40
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
2
312
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Иерархически ваши данные выглядят так:

SQL> with nodes_tab (node_id, short_name, parent_node_id) as
  2    (select 1, 'Parent Node-1', null from dual union all
  3     select 2, 'Child Node-2' , 1    from dual union all
  4     select 3, 'Child Node-3' , 1    from dual union all
  5     select 4, 'Child Node-4' , 2    from dual union all
  6     select 5, 'Child Node-5' , 2    from dual union all
  7     select 6, 'Child Node-6' , 4    from dual union all
  8     select 7, 'Child Node-7' , 6    from dual
  9    )
 10  select node_id,
 11         lpad(' ', 2 * level) || short_name as short_name,
 12         parent_node_id,
 13         connect_by_root short_name as root_node
 14  from nodes_tab
 15  start with parent_node_id is null
 16  connect by prior node_id = parent_node_id;

   NODE_ID SHORT_NAME                PARENT_NODE_ID ROOT_NODE
---------- ------------------------- -------------- -------------
         1   Parent Node-1                          Parent Node-1
         2     Child Node-2                       1 Parent Node-1
         4       Child Node-4                     2 Parent Node-1
         6         Child Node-6                   4 Parent Node-1
         7           Child Node-7                 6 Parent Node-1
         5       Child Node-5                     2 Parent Node-1
         3     Child Node-3                       1 Parent Node-1

7 rows selected.

SQL>

Обратите внимание на ROOT_NODE, который извлекается с помощью CONNECT_BY_ROOT — похоже, вам нужно это значение для всех SHORT_NAME.

Итак: если мы удалим отступ и применим то, что мы видели выше, вместе с соответствующим предложением ORDER BY, окончательный результат будет

SQL> with nodes_tab (node_id, short_name, parent_node_id) as
  2    (select 1, 'Parent Node-1', null from dual union all
  3     select 2, 'Child Node-2' , 1    from dual union all
  4     select 3, 'Child Node-3' , 1    from dual union all
  5     select 4, 'Child Node-4' , 2    from dual union all
  6     select 5, 'Child Node-5' , 2    from dual union all
  7     select 6, 'Child Node-6' , 4    from dual union all
  8     select 7, 'Child Node-7' , 6    from dual
  9    )
 10  select node_id,
 11         connect_by_root short_name as short_name
 12  from nodes_tab
 13  start with parent_node_id is null
 14  connect by prior node_id = parent_node_id
 15  order by node_id;

   NODE_ID SHORT_NAME
---------- -------------------------
         1 Parent Node-1
         2 Parent Node-1
         3 Parent Node-1
         4 Parent Node-1
         5 Parent Node-1
         6 Parent Node-1
         7 Parent Node-1

7 rows selected.

SQL>

Oracle 11GR2 и более поздние версии поддерживают рекурсивные CTE (которые являются частью стандартного SQL).

Итак, это работает:

with cte (node_id, parent_id, short_name, lev) as (
      select node_id, coalesce(parent_node_id, node_id), short_name, 1
      from nodes_tab
      union all
      select cte.node_id, nt.parent_node_id, nt.short_name, lev + 1
      from cte join
           nodes_tab nt
           on cte.parent_id = nt.node_id 
     )
select *
from (select cte.*, row_number() over (partition by node_id order by lev desc) as seqnum
      from cte
     ) cte
where seqnum = 1;

Здесь — это рабочий пример db<>.

Oracle поддерживает рекурсивный факторинг подзапросов (который вы называете рекурсивным CTE), начиная с версии 11g Release 2, выпущенной в сентябре 2009 года. Уже почти 10 лет.

Dr Y Wit 23.05.2019 17:29

Другие вопросы по теме