BEWERKEN: Ik heb de oplossing kunnen hervormen met behulp van Django-subquery's.
We kunnen de query vertalen naar Django ORM met behulp van Django's aggregates with SubQuery expressions
:
-
Maak een subquery om de laagste
close
op te halen voor elksymbol
:from django.db.models import OuterRef, Subquery, Min lows = StockHistory.objects.filter( stock=OuterRef('stock'), trading_date__gte='2017-05-04' ).values('stock__symbol') .annotate(low=Min('close')) .filter(trading_date__gte='2018-04-30')
-
Uitsplitsing:
filter
de queryset om alleen de aandelen te krijgen mettrading_date >= '2017-05-04'
.- "GROUP BY"
stock__symbol
(voorbeelden van groeperen op Djnago:GROUP BY ... MIN/MAX
,GROUP BY ... COUNT/SUM
). annotate
de laagste (low
) prijs voor elk element.filter
de queryset opnieuw om alleen de objecten met eenlow
. te krijgen veld dat voorkomt optrading_date >= '2018-04-30'
.
-
Tussenresultaat:
Hoewel we in dit stadium geen resultaat kunnen krijgen, ziet de subquery er als volgt uit:
[ {'stock__symbol': 'A', 'low': Decimal('105.00000')}, {'stock__symbol': 'C', 'low': Decimal('90.00000')} ]
We missen de
trading_date
.
-
-
Gebruik de subquery om de specifieke
StockHistory
op te halen objecten:StockHistory.objects.filter( stock__symbol=Subquery(lows.values('stock__symbol')), close=Subquery(lows.values('low')), trading_date__gte='2018-04-30' ).values('stock__symbol', 'trading_date', 'close') .order_by('stock__symbol')
-
Uitsplitsing:
lows.values('stock__symbol')
en lows.values('low') halen de respectievelijke waarden op uit de subquery.filter
de queryset tegen delows
subquery waarden. Ookfilter
tegen de opgegeven datum om lageclose
. te elimineren prijzen die vóór die datum plaatsvinden.- Verkrijg de opgegeven
values
. - Bestel het resultaat op
stock__symbol
(standaardascending
).
-
Resultaat:
[ { 'close': Decimal('105.00000'), 'trading_date': datetime.date(2018, 5, 3), 'stock__symbol': 'A' }, { 'close': Decimal('90.00000'), 'trading_date': datetime.date(2018, 5, 4), 'stock__symbol': 'C' } ]
-