sql >> Databáze >  >> RDS >> Mysql

kombinování měsíčních termínových dat s časovými řadami za první měsíc v MySQL

Vyžaduje to spoustu předběžné kontroly, ale v podstatě jsem musel vytvořit proměnné SQL založené na jednom kroku v čase, jako by to bylo v programu „nechte X =něco“, „nechte y =X + něco jiného“ , atd. Vytvořením nejvnitřnějších proměnných @SQLVars, jakmile je první deklarována, může být použita jako základ další proměnné a tak dále... Za prvé, zde je úplný dotaz, který můžete použít na svá data, která vytvářejí na základě jakéhokoli aktuálního data. Pokud svá data znáte lépe, možná je budete muset trochu upravit, ale myslím si, že díky tomu budete na dobré cestě.

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

Výsledek tohoto jednoho výše uvedeného dotazu vrátí JEDINÝ záznam (založený na aktuálním datu 31. ledna) k zobrazeníPrvní měsíc Druhý měsíc Třetí měsíc Čtvrtý měsícQ (12. března) U (12. dubna) V (12. května) X (12. června)

Nyní to vnořte do zbytku vašeho dotazu na vaše ID tickeru, něco jako

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()

Pokud se podíváte na nejvnitřnější @SqlVariables, jak bylo zmíněno dříve, je to jako skupina "nechte x=něco". Vždy potřebuji základ, abych mohl začít, takže nejprve získám první den daného měsíce do proměnné @FirstOfMonth zřetězením jakéhokoli roku aktuálního data + „-“ + měsíc aktuálního data + "-01" vždy začínat prvním dnem v měsíci... např.:Dnes je 31. ledna 2012 vytvoří řetězec '2012-01-01', který ve formátu rok/měsíc/datum okamžitě rozpozná MySQL jako formát data můžeme provádět aritmetiku data. Takže teď mám @FirstOfMonth ='2012-01-01'. Nyní musíme určit první den v týdnu, který toto datum představuje měsíce, ve kterém se nacházíme (proto @FDOW). Tím se vrátí hodnota od 1 do 7 (neděle =1, středa =4, so =7).

Z toho nyní musíme spočítat, kdy bude 2. středa v měsíci. Je-li dnem v týdnu neděle až středa (včetně), DRUHÁ středa je 12 dní MINUS den v týdnu. Příklad:Neděle 1. by byla středa 4., pak středa 11.... takže 12 - 1 (neděle) =11. Pokud by první den v měsíci BYLA středa, byl by to den v týdnu =4, ale 1. den v měsíci =st, druhá st. =8, takže 12 - 4 =8. Pokud by bylo datum čt, pá nebo sobota jako první v měsíci, den v týdnu by byl 5, 6 nebo 7 , MINIMÁLNÍ datum první středy by bylo 7, druhé středy by bylo 14, takže toto začíná 19 - kterýkoli den v týdnu... 5, 6, 7... Př:19 - 5 (čt den Týden) =14, 19 - 6 (pátek v týdnu) =13, 19 - 7 (so den v týdnu) =12.. Víme tedy, že první středa bude celý týden, takže nejdříve bude be je 7. a 14. místo na rozdíl od 1. a 8. (nejdříve v měsíci).

Nyní, když víme, KDY je 2. středa v měsíci, porovnejte to s datem, podle kterého spouštíme dotaz (tj.:curdate() ). Pokud je aktuální datum ZAPNUTO nebo PŘED (přes <=) DRUHÁ STŘEDA MĚSÍCE (@SWOM), pak chceme přeskočit pouze 1 měsíc... pokud jsme dále v měsíci, musíme přeskočit 2 měsíce.

Nyní sestavte data. Základem data pro 1. měsíc je první z aktuálního měsíce PLUS interval s libovolným počtem měsíců, který lze přeskočit. 2. měsíc je jeden měsíc po prvním, měsíc 3 jeden po měsíci 2 a měsíc 4 jeden po měsíci 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 )

Takže konečně máme všechny 4 měsíce, se kterými můžeme pracovat v jediném řádku ( vybrat ... ) sady výsledků sqlvars zobrazující něco jako

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

Nakonec, jakmile budou tato data v pořádku, můžeme nyní sestavit konkrétní řetězce, které hledáte, s příslušnými předponami „Q“, „U“, „V“ a „X“ plus levou 3 názvu měsíce se 2 číslice roku.

Takže, abyste získali všechny rozsahy dat a řetězce, které očekáváte, zeptejte se na svou druhou tabulku, jak jsem uvedl v úvodní části.

Doufám, že vám to pomůže a otevře vám oči ve zcela novém kontextu, jak oklamat SQL, aby... v podstatě udělal inline program, který vytvoří mnoho proměnných a z toho bude fungovat... Docela skvělé, co...

A po pravdě řečeno, toto je poprvé, co jsem konkrétně vyzkoušel tuto techniku, i když jsem v minulosti provedl mnoho dotazů pomocí SQLVars.




  1. Počítejte počet řádků v golangu

  2. Dotaz MySql Nahraďte hodnotu NULL prázdným řetězcem ve výběru

  3. rozdělení alfa a čísel pomocí sql

  4. výchozí sloupec s prázdným řetězcem