Django アプリには、'Proposal'、'ProposalRevision'、'Opinion'、'User' の 4 つのモデルがあります。簡単な定義は次のとおりです。
class User(models.Model):
pass
class Proposal(models.Model):
pass
class ProposalRevision(models.Model):
proposal = models.ForeignKey(Proposal)
created = models.DateTimeField()
class Opinion(models.Model):
user = models.ForeignKey(User)
proposal = models.ForeignKey(Proposal)
created = models.DateTimeField()
各提案には多くの改訂が含まれる場合があります。ユーザーは、特定の提案に対して多くの意見を持っている場合があります。私が作りたいクエリは次のとおりです。
最後の提案リビジョンが作成されてから特定のユーザーが意見を残していないすべての提案を取得します。
アプリケーションのユースケースは、意見を残す必要がある提案をユーザーに示したいというものです。
素朴に、私はこの方法でクエリを行うことを考えました:
Proposal.objects.annotate(
latest_revision=Max('proposalrevision__created')
).exclude(
opinion__user=user,
opinion__created__lte=F('latest_revision')
)
ただし、これは機能しません。これは、F 式が集計で機能しないためです (まだ)。
「余分な」クエリでこれを回避するために、必要なクエリを実行するバニラ SQL を書き始めましたが、「where」句で集計を使用することに行き詰まりました。私が扱っているSQLは次のようになります。
SELECT ...snip..., MAX("proposal_proposalrevision"."created") as "latest_revision"
FROM "proposal_proposal"
LEFT OUTER JOIN "proposal_proposalrevision" ON
("proposal_proposal"."id" = "proposal_proposalrevision"."proposal_id")
WHERE "proposal_proposal"."id" NOT IN (
SELECT (U1."proposal_id") FROM "proposal_opinion" U1
WHERE (
U1."user_id" = 1 AND U1."proposal_id" IS NOT NULL AND
U1."created" > "latest_proposal"
)
)
GROUP BY ...snip...
SQLite でエラー " misuse of aggregate: MAX()
" が表示されます。これは、変数名 " latest_proposal
" を使用するか、集計関数の繰り返しに置き換えるかに関係なく保持されますMAX("proposal_proposalrevision"."created")
。
集計を使用して返されたセットをフィルタリングするために、このクエリを作成するにはどうすればよいでしょうか?