РЕДАКТИРАНЕ: Успях да реформирам решението с помощта на подзаявки на Django.
Можем да преведем заявката в Django ORM с помощта на aggregates with SubQuery expressions
:
-
Създайте подзаявка, за да извлечете най-ниското
close
за всекиsymbol
: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')
-
Разбивка:
filter
набора от заявки, за да получите само акциите сtrading_date >= '2017-05-04'
.- „GROUP BY“
stock__symbol
(примери за група от в Djnago:GROUP BY ... MIN/MAX
,GROUP BY ... COUNT/SUM
). annotate
най-ниската (low
) цена за всеки елемент.filter
набора от заявки отново, за да получите само обектите сlow
поле, което се появява наtrading_date >= '2018-04-30'
.
-
Междинен резултат:
Въпреки че не можем да получим резултат на този етап, подзаявката ще изглежда така:
[ {'stock__symbol': 'A', 'low': Decimal('105.00000')}, {'stock__symbol': 'C', 'low': Decimal('90.00000')} ]
Липсва ни
trading_date
.
-
-
Използвайте подзаявката, за да извлечете конкретната
StockHistory
обекти: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')
-
Разбивка:
lows.values('stock__symbol')
и lows.values('low') извличат съответните стойности от подзаявката.filter
наборът от заявки срещуlows
стойности на подзаявка. Също такаfilter
срещу посочената дата, за да се елиминира нискияclose
цени, настъпващи преди тази дата.- Вземете посочените
values
. - Поръчайте резултата по
stock__symbol
(по подразбиранеascending
).
-
Резултат:
[ { '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' } ]
-