EDITAR: Consegui reformar a solução usando subconsultas do Django.
Podemos traduzir a consulta para o Django ORM usando o
aggregates with SubQuery expressions
:-
Crie uma subconsulta para recuperar oclose
mais baixo para cadasymbol
:
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')
-
Detalhamento:
filter
o conjunto de consultas para obter apenas as ações comtrading_date >= '2017-05-04'
.- "GROUP BY"
stock__symbol
(exemplos de group by no Djnago:GROUP BY ... MIN/MAX
,GROUP BY ... COUNT/SUM
). annotate
o mais baixo (low
) preço para cada elemento.filter
o queryset novamente para obter apenas os objetos com umlow
campo que ocorre emtrading_date >= '2018-04-30'
.
-
Resultado intermediário:
Embora não possamos obter um resultado neste estágio, a subconsulta ficará assim:
[ {'stock__symbol': 'A', 'low': Decimal('105.00000')}, {'stock__symbol': 'C', 'low': Decimal('90.00000')} ]
Falta atrading_date
.
-
-
Utilize a subconsulta para recuperar oStockHistory
específico objetos:
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')
-
Detalhamento:
lows.values('stock__symbol')
e lows.values('low') recuperam os respectivos valores da subconsulta.filter
o conjunto de consultas em relação aoslows
valores de subconsulta. Tambémfilter
em relação à data especificada para eliminarclose
baixo preços que ocorrem antes dessa data.- Obter os
values
especificados . - Ordenar o resultado por
stock__symbol
(por padrãoascending
).
-
Resultado:
[ { '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' } ]
-