sql >> Database teknologi >  >> RDS >> Mysql

Hvordan konverterer jeg denne komplekse SQL til en Django-modelforespørgsel?

EDIT: Det lykkedes mig at reformere løsningen ved hjælp af Django underforespørgsler.

Vi kan oversætte forespørgslen til Django ORM ved hjælp af Djangos aggregates with SubQuery expressions :

  1. Opret en underforespørgsel for at hente den laveste close for hvert 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')
    
    • Opdeling:

      • filter forespørgslen for kun at få aktierne med trading_date >= '2017-05-04' .
      • "GROUP BY" stock__symbol (eksempler på gruppe af i Djnago:GROUP BY ... MIN/MAX , GROUP BY ... COUNT/SUM ).
      • annotate den laveste (low ) pris til hvert element.
      • filter forespørgselssættet igen for kun at få objekter med en low felt, der forekommer på trading_date >= '2018-04-30' .
    • Mellemresultat:

      Selvom vi ikke kan få et resultat på dette stadium, vil underforespørgslen se sådan ud:

      [
          {'stock__symbol': 'A', 'low': Decimal('105.00000')},            
          {'stock__symbol': 'C', 'low': Decimal('90.00000')}
      ]
      

      Vi mangler trading_date .

  2. Brug underforespørgslen til at hente den specifikke StockHistory objekter:

    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')
    
    • Opdeling:

      • lows.values('stock__symbol') og lows.values('low') henter de respektive værdier fra underforespørgslen.
      • filter forespørgslen mod lows underforespørgselsværdier. Også filter mod den angivne dato for at eliminere lav close priser, der fandt sted før denne dato.
      • Hent de angivne values .
      • Bestil resultatet efter stock__symbol (som standard ascending ).
    • Resultat:

      [
          {
              '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'
          }
      ]
      


  1. Beregn Percentilværdi ved hjælp af MySQL

  2. MySQL:Opdater kun et felt, hvis betingelsen er opfyldt

  3. Guide til design af database til lagerstyringssystem i MySQL

  4. Mysql tæller forekomst efter gruppe