Django ORM подзапрос с оконной функцией - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь выполнить этот запрос с помощью ORM Джанго:

SELECT
  id,
  pn,
  revision,
  description
FROM (SELECT
        id,
        pn,
        revision,
        MAX(revision)
        OVER (
          PARTITION BY pn ) max_rev,
        description
      FROM table) maxarts
WHERE revision = max_rev

Результатом должен быть набор запросов, я пробовал каждую комбинацию Window / OuterRef / Subquery, которую я знаю, но безуспешно.Нужно ли использовать необработанный запрос?

Заранее спасибо Марко

РЕДАКТИРОВАТЬ # 1:

Я постараюсь объяснить лучше, яесть модель, которая выглядит следующим образом:

class Article(models.Model):
  pn = models.CharField()
  revision = models.CharField()
  description = models.CharField()

  class Meta:
    unique_together = [("pn", "revision"), ]

Данные примерно такие:

pn1    rev1    description
pn1    rev2    description
pn2    rev1    anotherdescription
pn1    rev3    description
pn2    rev2    anotherdescription

Мне нужно иметь набор запросов, содержащий только значение Max ("revision"), котороеувеличивается каждый раз, когда пользователь вносит изменения в объект.Надеюсь, теперь это станет понятнее.Спасибо!

РЕДАКТИРОВАТЬ # 2

Как и предполагалось, я пишу то, что я уже пробовал:

Необработанный SQL с использованием запроса, написанного впервое сообщение, выбрав только поле id и передав его в ORM как id__in = ids.Медленно, чертовски непригодно.

Объявлена ​​функция WIndow для использования в качестве фильтра:

Article.objects.annotate(max_rev=Window(expression=Max("revision"), partition_by=F("pn"))).filter(revision=F("max_rev"))

Но Джанго пожаловался, что я не могу использовать оконную функцию в предложении where (это правильно).

Затем я попытался использовать окно как подзапрос:

window_query = Article.objects.annotate(max_rev=Window(expression=Max("revision"), partition_by=F("pn")))
result = Article.objects.filter(revision= Subquery(window_query)

Я также пытался использовать OuterRef, чтобы использовать аннотацию max_rev в качестве соединения, не повезло.У меня нет идей!

1 Ответ

0 голосов
/ 05 июня 2018

Таким образом, каждый раз, когда вносятся изменения в статью, создается строка в таблице?

Если это так, все, что вам нужно сделать, это выполнить запрос подсчета, который подсчитывает все строки и группирует их в соответствии споле 'pn'.Если вы хотите использовать функцию Max, я бы предложил заменить поле 'pn' на IntegerField или DecimalField вместо использования CharField.Хотя в зависимости от того, где находится ваше приложение, это может быть довольно сложно.

from django.db.models import Count

Article.objects.values('pn').annotate(maxvalues=Count('pn'))
...