試してみませんか
from stocks.models import StockHistory, Stock
from django.db.models import OuterRef, Subquery, F, Min
low = StockHistory.objects.filter(
stock=OuterRef('stock'), trading_date__gt='2017-05-04'
).order_by('close')
qs = StockHistory.objects.annotate(
low=Subquery(low.values('close')[:1])
)
qs = qs.filter(low=F('close')).filter(trading_date__gte='2018-04-30')
qs = qs.values('stock__symbol', 'low').order_by('stock__symbol', 'low')
qs = qs.annotate(mtd=Min('trading_date'))
qs = qs.values_list('stock__symbol', 'mtd', 'low')
qs = qs.order_by('stock__symbol', 'low')
結果:
>>> qs
<QuerySet [('A', datetime.date(2018, 5, 2), Decimal('105.00000')), ('C', datetime.date(2018, 5, 4), Decimal('90.00000'))]>
SQLコードは
>>> print(qs.query)
SELECT "stocks_stock"."symbol",
(SELECT U0."close"
FROM "stocks_stockhistory" U0
WHERE (U0."stock_id" = ("stocks_stockhistory"."stock_id")
AND U0."trading_date" > 2017-05-04)
ORDER BY U0."close" ASC LIMIT 1) AS "low",
MIN("stocks_stockhistory"."trading_date") AS "mtd"
FROM "stocks_stockhistory"
INNER JOIN "stocks_stock"
ON ("stocks_stockhistory"."stock_id" = "stocks_stock"."id")
WHERE (
(SELECT U0."close"
FROM "stocks_stockhistory" U0
WHERE (U0."stock_id" = ("stocks_stockhistory"."stock_id") AND U0."trading_date" > 2017-05-04)
ORDER BY U0."close" ASC LIMIT 1) = ("stocks_stockhistory"."close")
AND "stocks_stockhistory"."trading_date" >= 2018-04-30)
GROUP BY "stocks_stock"."symbol",
(SELECT U0."close"
FROM "stocks_stockhistory" U0
WHERE (U0."stock_id" = ("stocks_stockhistory"."stock_id") AND U0."trading_date" > 2017-05-04)
ORDER BY U0."close" ASC LIMIT 1)
ORDER BY "stocks_stock"."symbol" ASC, "low" ASC