EDITAR: Logré reformar la solución usando subconsultas de Django.
Podemos traducir la consulta a Django ORM usando Django aggregates with SubQuery expressions
:
-
Cree una subconsulta para recuperar el
close
más bajo por 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')
-
Desglose:
filter
el conjunto de consultas para obtener solo las acciones contrading_date >= '2017-05-04'
.- "AGRUPAR POR"
stock__symbol
(ejemplos de group by en Djnago:GROUP BY ... MIN/MAX
,GROUP BY ... COUNT/SUM
). annotate
el más bajo (low
) precio a cada elemento.filter
el conjunto de consultas nuevamente para obtener solo los objetos con unlow
campo que aparece entrading_date >= '2018-04-30'
.
-
Resultado intermedio:
Aunque no podemos obtener un resultado en esta etapa, la subconsulta se verá así:
[ {'stock__symbol': 'A', 'low': Decimal('105.00000')}, {'stock__symbol': 'C', 'low': Decimal('90.00000')} ]
Nos falta la
trading_date
.
-
-
Utilice la subconsulta para recuperar el
StockHistory
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')
-
Desglose:
lows.values('stock__symbol')
y lows.values('low') recuperan los valores respectivos de la subconsulta.filter
el conjunto de consultas contra loslows
valores de subconsulta. Tambiénfilter
contra la fecha especificada para eliminar elclose
bajo precios anteriores a esa fecha.- Obtener los
values
especificados . - Ordene el resultado por
stock__symbol
(por defectoascending
).
-
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' } ]
-