是否可以使用Django ORM将子查询结果与标量值进行比较?我很难转换它:
SELECT payment_subscription.*
FROM payment_subscription payment_subscription
JOIN payment_recurrent payment_recurrent ON payment_subscription.id = payment_recurrent.subscription_id
WHERE
payment_subscription.status = 1
AND (SELECT expiration_date
FROM payment_transaction payment_transaction
WHERE payment_transaction.company_id = payment_subscription.company_id
AND payment_transaction.status IN ('OK', 'Complete')
ORDER BY payment_transaction.expiration_date DESC, payment_transaction.id DESC
LIMIT 1) <= ?
要点是:
答案 0 :(得分:1)
您可以(从Django 1.11开始)对子查询进行批注,然后对其进行切片以确保仅获得“第一”结果。然后,您可以通过比较所需的值来过滤该子查询注释。
from django.db.models.expressions import Subquery, OuterRef
expiration_date = Transaction.objects.filter(
company=OuterRef('company'),
status__in=['OK', 'Complete'],
).order_by('-expiration_date').values('expiration_date')[:1]
Subscription.objects.filter(status=1).annotate(
expiration_date=Subquery(expiration_date),
).filter(expiration_date__lte=THE_DATE)
但是...
当前,这可能会导致非常糟糕的性能:您的数据库将对子查询进行两次评估(一次是在where子句中,通过过滤器,一次是在select子句中,通过注释)。目前正在解决该问题,但目前尚未完成。
答案 1 :(得分:0)
Subscription.objects.annotate(
max_expiraton_date=Max('transaction__expiration_date')
).filter(
status=1,
recurrent__isnull=False, # [inner] join with recurrent
transaction__status__in=['OK', 'Complete'],
max_expiraton_date=date_value
)
这会产生其他SQL查询,但会获得相同的Subscription
个对象。