powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / рекурсивно обойти таблицу, как направленный граф
13 сообщений из 13, страница 1 из 1
рекурсивно обойти таблицу, как направленный граф
    #39378886
no_username
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет!

У меня есть таблица

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
       ip       |                                      ports
----------------+--------------------------------------------------------------------------------------
 10.1.1.1       | {"port20": {"n": "10.1.1.2"}}
 10.1.1.2       | {"port5": {"n": "10.1.1.3"}, "port4": {"n": "10.1.1.1"}}
 10.1.1.3       | {"port1": {"n": "10.1.1.4"}, "port25": {"n": "10.1.1.2"}}
 10.1.1.4       | {"port6": {"n": "10.1.1.5"}, "port1": {"n": "10.1.1.3"}}
 10.1.1.5       | {"port8": {"n": "10.1.1.4"}}
 10.1.1.6       | {"port1": {"n": "10.1.1.7"}}
 10.1.1.7       | {"port2": {"n": "10.1.1.6"}}


я бы хотел имея только ip, вернуть все строки, которые связаны между собой, написал запрос, но не понимаю как развернуть вторую часть
Код: sql
1.
2.
3.
4.
5.
6.
WITH RECURSIVE r AS (
    SELECT value->>'n' n FROM jsonb_each((SELECT ports FROM switches WHERE ip = '10.1.1.3'))
  UNION
    SELECT value->>'n' FROM jsonb_each((SELECT ports FROM switches s WHERE s.ip = r.n))
)
SELECT * FROM switches WHERE ip IN (SELECT * FROM r)


Возвращает ошибку
Код: sql
1.
ERROR:  missing FROM-clause entry for table "r"



Подскажите, пожалуйста, как составить правильно вторую часть, после UNION'a. В итоге при запросе ip = 10.1.1.3 должны вернуться все строки, с ip 1,2,3,4,5, а при запросе ip = 1.1.1.6 только ip c 6 и 7

Спасибо!
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378887
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no_username
Код: sql
1.
2.
3.
4.
5.
6.
WITH RECURSIVE r AS (
    SELECT value->>'n' n FROM jsonb_each((SELECT ports FROM switches WHERE ip = '10.1.1.3'))
  UNION
    SELECT value->>'n' FROM jsonb_each((SELECT ports FROM switches s WHERE s.ip = r.n))
)
SELECT * FROM switches WHERE ip IN (SELECT * FROM r)


Возвращает ошибку
Код: sql
1.
ERROR:  missing FROM-clause entry for table "r"


Подскажите, пожалуйста, как составить правильно вторую часть, после UNION'a. В итоге при запросе ip = 10.1.1.3 должны вернуться все строки, с ip 1,2,3,4,5, а при запросе ip = 1.1.1.6 только ip c 6 и 7
В выделенной строке, алиас `r` неопределён.
Если хотите привязаться к самому себе в рекурсивном запросе, то нужно явно это делать во FROM-части запроса.
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378894
no_username
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovВ выделенной строке, алиас `r` неопределён.
Если хотите привязаться к самому себе в рекурсивном запросе, то нужно явно это делать во FROM-части запроса.

Я понимаю что значит ошибка, но не понимаю как переделать вторую часть.
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378919
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no_username,

Что не так в данном запросе:
Код: sql
1.
2.
3.
SELECT *
  FROM invoice
 WHERE invoice.client_id=client.id AND client.created_at >= now() - INTERVAL '1 week';


И как испроавить?
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378922
no_username
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovno_username,

Что не так в данном запросе:
Код: sql
1.
2.
3.
SELECT *
  FROM invoice
 WHERE invoice.client_id=client.id AND client.created_at >= now() - INTERVAL '1 week';


И как испроавить?

Нет клиента, надо его заджойнить, что-то вроде

Код: sql
1.
2.
3.
4.
SELECT *
FROM invoice
JOIN client on invoice.client_id=client.id
WHERE client.created_at >= now() - INTERVAL '1 week';



Как я понимаю, это что-то типа подсказки... С простыми полями все просто, но вот jsonb_each все ломает, не понимаю как достать следующих соседей все равно.
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378926
no_username
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorov,

я уже доходил до
Код: sql
1.
select s.ports::text from switches s join r on s.ip = r.n



но так и не понял как достать значения соседей из s.ports, всю документацию облазил по функциям jsonb уже...
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378929
Hawkmoon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то мне ТС напоминает статью из ИТ-энциклопедии.

Рекурсия - см. рекурсия.
и
Для того, чтобы понять рекурсию, нужно сначала понять рекурсию.


А по делу - вам же черным по белому написано, что
если объявил with recursive blablabla, то будь добр, выбери из этого блаблабла:

WITH RECURSIVE included_parts (sub_part, part, quantity) AS (
SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
UNION ALL
SELECT p.sub_part, p.part, p.quantity
FROM included_parts pr , parts p
WHERE p.part = pr.sub_part
)
SELECT sub_part, SUM(quantity) as total_quantity
FROM included_parts
GROUP BY sub_part


где рекурсия-то в рекурсивном запросе???
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378930
no_username
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вроде как сделал, но результат довольно медленный получается

Код: sql
1.
select je.value->>'n' from switches s join r on s.ip = r.n cross join jsonb_each(s.ports) je
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378932
Hawkmoon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
еще бы.
10.1.1.6 | {"port1": {"n": "10.1.1.7"}}
10.1.1.7 | {"port2": {"n": "10.1.1.6"}}

оно точно возвращается для этой бесконечной рекурсии? )))
где заглушка-то на (эмуляцию nocycle, прастихосспади, но я нынче ораклоид, рекурсивные with-ы позабыл)

не, это хорошо, что оно вернется, прогруппирует, т.к. union без all, и выдаст результат...
но лучше в рекурсии смотреть детект "мы тут уже были", чего я не наблюдаю.

например, как тут:
http://stackoverflow.com/questions/25058906/nocycle-in-postgres
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378942
no_username
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hawkmoon,

медленно это 0.25 сек https://explain.depesz.com/s/dcnT
да, оно возвращается, но слишком много селектов делается, мне проще выбрать все данные и перебрать алгоритмом в коде. Я думал может быть будет быстро внутри постгреса это сделать, но нет.

По nocycle идею понял, спасибо. Только там каждый раз создается новый array, и в финальный результат попадает много дублей, по скорости - так же. Надо делать какой-то глобальный массив visited, но это уже PLPQSQL надо использовать.
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39378950
Hawkmoon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no_username,

не массив visited, а отсечение в выборке, "были мы уже тут или нет" по уникальной идентификации узла обхода.
Для вашего случая - ip - вполне себе уникальная идентификация.

Дальше нужно думать и копать, сходу не получится. но на мой взгляд, на SO идет дискач вполне себе конструктивный, с отсечением "был я тут или нет" по pk_id.
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39380659
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
no_usernameда, оно возвращается, но слишком много селектов делается, мне проще выбрать все данные и перебрать алгоритмом в коде. Я думал может быть будет быстро внутри постгреса это сделать, но нет.Да, вполне вероятно, что вычисление в приложении окажется на порядок быстрее рекурсивного запроса.
...
Рейтинг: 0 / 0
рекурсивно обойти таблицу, как направленный граф
    #39380661
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример с проверкой зацикливания есть в документации (см. cycle).

https://www.postgresql.org/docs/9.6/static/queries-with.html
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / рекурсивно обойти таблицу, как направленный граф
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]