#django #postgresql #recursion #sql
#django #postgresql #рекурсия #sql
Вопрос:
Мое требование состоит в том, чтобы написать sql-запрос, чтобы получить количество событий с учетом субрегиона (сбоя), которые произошли для управляемых объектов. Моя база данных — postgres 8.4. Позвольте мне объяснить, используя структуру таблицы.
Мои таблицы в django: управляемый объект:
class Managedobject(models.Model):
name = models.CharField(max_length=200, unique=True)
iscontainer = models.BooleanField(default=False,)
parentkey = models.ForeignKey('self', null=True)
Таблица событий:
class Event(models.Model):
Name = models.CharField(verbose_name=_('Name'))
foid = models.ForeignKey(Managedobject)
Записи управляемых объектов:
NOC
Chennai
MO_1
MO_2
MO_3
Mumbai
MO_4
MO_5
MO_6
Delhi
Bangalore
IP
Calcutta
Cochin
Записи событий:
event1 MO_1
event2 MO_2
event3 MO_3
event4 MO_5
event5 MO_6
Теперь мне нужно получить количество событий для всех субрегионов. Например,
for NOC region:
Chennai - 3
Mumbai - 2
Delhi - 0
Bangalore - 0
Пока я могу получить результат в двух разных запросах.
-
Получаем подобласти.
select id from managedobject where iscontainer = True and parentkey = 3489
-
Для каждой области (используя цикл for), получите количество следующим образом:
SELECT count(*) from event ev WHERE ev.foid IN ( WITH RECURSIVE q AS ( SELECT h FROM managedobject h WHERE parentkey = 3489 UNION ALL SELECT hi FROM q JOIN managedobject hi ON hi.parentkey = (q.h).id ) SELECT (q.h).id FROM q )
Пожалуйста, помогите объединить запросы, чтобы сделать их одним запросом и получить 5 лучших регионов. Поскольку запрос в django сложный, я использую необработанный sql-запрос.
Комментарии:
1. вам нужно это
iscontainer
поле? если parentkey = None, то объект не является контейнером, а если Managedobject имеет parentkey, то это контейнер?2. @krieger. Спасибо за усилия. Здесь контейнер имеет другое значение. Уровень отношений родитель / потомок в таблице Managedobject бесконечен. Если запись помечена как контейнер, это логический объект, только что добавленный для группировки. Даже запись MO_1 может иметь дочерний MO_11, но это не контейнер, поскольку он представляет физическую сущность.
3. ооо, я вижу, я неправильно истолковал ваш первоначальный вопрос. Я рассмотрю это немного иначе. извините за это. Я думал, что MO_1 были событиями, они просто управляемый объект, события тоже были связаны.
Ответ №1:
Я получил запрос:
WITH RECURSIVE q AS (
SELECT h,
1 AS level,
id AS ckey,
displayname as dname
FROM managedobject h
WHERE parentkey = 3489
and logicalnode=True
UNION ALL
SELECT hi,
q.level 1 AS level,
ckey,
dname
FROM q
JOIN managedobject hi ON hi.parentkey = (q.h).id
)
SELECT count(ckey) as ccount,
ckey,
dname
FROM q
JOIN event as ev on ev.foid_id = (q.h).id
GROUP BY ckey, dname
ORDER BY ccount DESC
LIMIT 5
Комментарии:
1. Что делает это выражение:
ev.foid_id = (q.h).id
? Это опечатка?2. Нет, это запущенный запрос. В Django к полю foreignkey будет добавлен «_id». В рекурсивном запросе postgres вы должны получить доступ к полю как «(q.h).id».
3. Я никогда не видел такого синтаксиса с рекурсивным CTE. Я бы сказал,
q.id
этого должно быть достаточно для внутреннего запроса. Внешний, вероятно, должен использоватьq.ckey