sql >> Database >  >> RDS >> Mysql

Hoe zet ik deze complexe SQL om in een Django-modelquery?

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 :

  1. Maak een subquery om de laagste close op te halen voor elk 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')
    
    • Uitsplitsing:

      • filter de queryset om alleen de aandelen te krijgen met trading_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 een low . te krijgen veld dat voorkomt op trading_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 .

  2. 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 de lows subquery waarden. Ook filter tegen de opgegeven datum om lage close . te elimineren prijzen die vóór die datum plaatsvinden.
      • Verkrijg de opgegeven values .
      • Bestel het resultaat op stock__symbol (standaard ascending ).
    • 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'
          }
      ]
      


  1. Favoriete trucs voor het afstemmen van prestaties

  2. WordPress installeren met WP-CLI

  3. Databasetabel bestaat niet volgens de Android Studio-compiler

  4. Schrijven naar specifieke schema's met RPostgreSQL