sql >> Database >  >> RDS >> Mysql

het combineren van maandelijkse futures-gegevens tot tijdreeksen van de eerste maand in MySQL

Het vergt veel controle vooraf, maar in wezen moest ik SQL-variabelen bouwen op basis van één stap tegelijk, alsof het in een programma was van "let X =something", "let y =X + something else" , enz. Door de meest innerlijke @SQLVars-variabelen te bouwen, kan de eerste, zodra deze is gedeclareerd, worden gebruikt als basis voor de volgende variabele, enzovoort... Ten eerste, hier is de volledige query die u kunt toepassen op uw gegevens die worden opgebouwd gebaseerd op wat de huidige datum ook is. Als je je gegevens beter kent, moet je ze misschien wat aanpassen, maar ik denk dat je hiermee een eind op weg bent.

select
      CONCAT( 'Q (', LEFT( MonthName( DateBasis.dMonth1 ), 3 ), ' ', RIGHT( Year( DateBasis.dMonth1 ), 2 ), ')' ) as FirstMonth,
      CONCAT( 'U (', LEFT( MonthName( DateBasis.dMonth2 ), 3 ), ' ', RIGHT( Year( DateBasis.dMonth2 ), 2 ), ')' ) as SecondMonth,
      CONCAT( 'V (', LEFT( MonthName( DateBasis.dMonth3 ), 3 ), ' ', RIGHT( Year( DateBasis.dMonth3 ), 2 ), ')' ) as ThirdMonth,
      CONCAT( 'X (', LEFT( MonthName( DateBasis.dMonth4 ), 3 ), ' ', RIGHT( Year( DateBasis.dMonth4 ), 2 ), ')' ) as FourthMonth
   from   
      ( select @FirstOfMonth dFirstOfMonth,
               @FDOM nWeekDay,
               @SWOM nSecondWedOfMonth,
               @SkipMonths nSkip,
               @Month1 dMonth1,
               @Month2 dMonth2,
               @Month3 dMonth3,
               @Month4 dMonth4
           from
              ( select @FirstOfMonth := CONCAT( year(curdate()), '-', month( curdate()), '-01' ),
                       @FDOW := DayOfWeek( @FirstOfMonth ),
                       @SWOM := if( @FDOW <= 4, 12, 19) - @FDOW,
                       @SkipMonths := if( day( CurDate()) <= @SWOM, 1, 2 ),
                       @Month1 := date_add( @FirstOfMonth, interval 0 +  @SkipMonths month ),
                       @Month2 := date_add( @Month1, interval 1 month ),
                       @Month3 := date_add( @Month2, interval 1 month ),
                       @Month4 := date_add( @Month3, interval 1 month )
                       ) sqlvars
      ) DateBasis

Het resultaat van deze ene query hierboven retourneert een ENKEL record (gebaseerd op de huidige datum van 31 januari) om FirstMonth SecondMonth ThirdMonth FourthMonthQ (12 maart) U (12 april) V (12 mei) X (12 juni) weer te geven

Nest dit nu in de rest van uw zoekopdracht voor uw ticker-ID's, zoiets als

SELECT hist.date, 
       hist.ticker_id, 
       hist.settle_price, 
       hist.volume 
   FROM 
      hist,
      ( entire select statement above ) FinalDates

   WHERE 
          hist.ticker_id IN ( FinalDates.FirstMonth,
                              FinalDates.SecondMonth,
                              FinalDates.ThirdMonth,
                              FinalDates.FourthMonth )
      and hist.trade_dt = curdate()

Als je naar de binnenste @SqlVariables kijkt, zoals eerder vermeld, is het als een stelletje "let x=something". Ik heb altijd een basis nodig om te beginnen, dus ik krijg eerst de eerste dag van een bepaalde maand in een variabele @FirstOfMonth door een aaneenschakeling te doen van wat het jaar ook is van de huidige datum + "-" + maand van de huidige datum + "-01" om altijd op de eerste van de maand te beginnen... vb:Vandaag is het 31 jan, 2012 zal een string van '2012-01-01' opbouwen die in jaar/maand/datum formaat onmiddellijk herkend wordt door MySQL als datumformaat kunnen we datumberekeningen uitvoeren. Dus nu heb ik @FirstOfMonth ='2012-01-01'. Nu moeten we de eerste dag van de week bepalen die deze datum vertegenwoordigt van de maand waarin we ons bevinden (vandaar @FDOW). Dit retourneert een waarde van 1-7 (zondag =1, wo =4, za =7).

Hieruit moeten we nu berekenen wanneer de 2e woensdag van de maand zal zijn. Als de dag van de week zondag tot en met woensdag is, is de TWEEDE woensdag 12 dagen MIN de dag van de week. Bijv:zondag de 1e zou wo 4e zijn, dan wo de 11e... dus 12 - 1 (zondag) =11. Als de eerste dag van de maand een wo WAS, zou het een dag van de week =4 zijn, maar de 1e van de maand =wo, de tweede wo =8, dus 12 - 4 =8. Als de datum nu do, vr of za was als de eerste van de maand, zou de dag van de week een 5, 6 of 7 zijn De MINIMALE datum van de eerste woensdag zou 7 zijn, de tweede woensdag zou 14 zijn, dus dit begint met 19 - ongeacht de dag van de week... 5, 6, 7... Vb:19 - 5 (do dag van Week) =14, 19 - 6 (vrijdag van de week) =13, 19 - 7 (za-dag van de week) =12.. Dus we weten dat de eerste woensdag de volledige week zal zijn, dus op zijn vroegst be is 7e en 14e in tegenstelling tot 1e en 8e (vroegste van de maand).

Nu we weten WANNEER de 2e woensdag van de maand is, vergelijk dat dan met de datum waarop we de query uitvoeren op basis van (dwz:curdate() ). Als de huidige datum AAN is of VOOR (via <=) de TWEEDE WO van MAAND (@SWOM), dan willen we maar 1 maand overslaan... als we verder in de maand zijn, moeten we 2 maanden overslaan.

Bouw nu de datums uit. De datumbasis voor maand 1 is de eerste van de huidige maand PLUS een interval van hoeveel maanden u ook mag overslaan. Maand 2 is een maand na de eerste, maand 3 een afgelopen maand 2 en maand 4 een afgelopen maand 3.

@FirstOfMonth := CONCAT( year(curdate()), '-', month( curdate()), '-01' ),
@FDOW := DayOfWeek( @FirstOfMonth ),
@SWOM := if( @FDOM <= 4, 12, 19) - @FDOM,
@SkipMonths := if( day( CurDate()) <= @SWOM, 1, 2 ),
@Month1 := date_add( @FirstOfMonth, interval 0 +  @SkipMonths month ),
@Month2 := date_add( @Month1, interval 1 month ),
@Month3 := date_add( @Month2, interval 1 month ),
@Month4 := date_add( @Month3, interval 1 month )

Dus we hebben eindelijk alle 4 maanden basis om mee te werken in een enkele rij van (selecteer ...) sqlvars resultaatset die zoiets laat zien als

@Month1     @Month2     @Month3     @Month4
2012-03-01  2012-04-01  2012-05-01  2012-06-01 ... the four months out

Eindelijk, zodra deze gegevens in orde lijken, kunnen we nu de specifieke strings die u zoekt uitbouwen met de respectievelijke "Q", "U", "V" en "X" voorvoegsels plus de linker 3 van de maandnaam met de 2 cijfer jaar.

Dus, nu je alle datumbereiken en tekenreeksen krijgt die je verwacht, vergelijk dit met je andere tabel zoals ik in de initiaal heb vermeld.

Ik hoop dat dit je helpt en je ogen opent voor een compleet nieuwe context om SQL te misleiden tot... in wezen een inline programma doen om veel variabelen te creëren en van daaruit te werken... Best cool he...

En om eerlijk te zijn, dit is de eerste keer dat ik deze techniek specifiek heb uitgeprobeerd, hoewel ik in het verleden veel queries heb gedaan met SQLVars.




  1. Hoe de mediaan te berekenen in MySQL

  2. Waarom is de gegeven syntaxis geldig in mysql?

  3. De voordelen van MariaDB's Certified Associate-programma ontsluiten

  4. Hoe kan ik NULL-gegevens invoegen in de MySQL-database met Python?