Mysql
 sql >> база данни >  >> RDS >> Mysql

комбиниране на месечни фючърсни данни с времеви серии от предния месец в MySQL

Отнема много предварителна проверка, но по същество трябваше да изградя SQL променливи въз основа на една стъпка в даден момент, сякаш беше в програма от "нека X =нещо", "нека y =X + нещо друго" , и т.н. Чрез изграждането на повечето вътрешни променливи @SQLVars, след като първата е декларирана, тя може да се използва като основа на следващата променлива и така нататък... Първо, ето пълната заявка, която можете да приложите към вашите данни, които изграждат въз основа на каквато и да е текущата дата. Познавайки данните си по-добре, може да се наложи да ги настроите малко, но мисля, че това ще ви помогне да вървите добре.

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

Резултатът от тази една заявка по-горе ще върне ЕДИНСТВЕН запис (въз основа на текущата дата 31 януари) за показванеFirstMonth SecondMonth ThirdMonth FourthMonthQ (12 март) U (12 април) V (12 май) X (12 юни)

Сега вложете това в останалата част от вашата заявка за вашите идентификационни номера на тикер, нещо като

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

Ако погледнете най-вътрешните @SqlVariables, както бе споменато по-рано, е като куп "нека x=нещо". Винаги имам нужда от база, за да започна, така че първо получавам първия ден от даден месец в променлива @FirstOfMonth, като правя конкатенация на каквато и да е годината на текущата дата + "-" + месец на текущата дата + "-01" винаги да започва на първо число на месеца... напр.:Днес е 31 януари 2012 г. ще изгради низ от '2012-01-01', който във формат година/месец/дата се разпознава незабавно от MySQL като формат на дата можем да извършваме аритметика за дата. Така че сега имам @FirstOfMonth ='2012-01-01'. Сега трябва да определим първия ден от седмицата, който тази дата представлява от месеца, в който се намираме (следователно @FDOW). Това ще върне стойност от 1-7 (неделя =1, сряда =4, събота =7).

От това сега трябва да изчислим кога ще бъде 2-та сряда от месеца. Ако денят от седмицата е от неделя до (включително) сряда, ВТОРАТА сряда е 12 дни МИНУС денят от седмицата. Например:1-ва неделя ще бъде сряда 4-та, след това сряда 11-та... така че 12 - 1 (неделя) =11. Ако първият ден от месеца е сряда, това ще бъде ден от седмицата =4, но 1-во число на месеца =ср., втората ср. =8, така че 12 - 4 =8. Сега, ако датата е била четвъртък, петък или събота като първи от месеца, денят от седмицата ще бъде 5, 6 или 7 МИНИМАЛНАТА дата на първата сряда ще бъде 7, втората сряда ще бъде 14, така че това започва с 19 - независимо от деня от седмицата... 5, 6, 7... Напр.:19 - 5 (четвъртък ден от Седмица) =14, 19 - 6 (петък ден от седмицата) =13, 19 - 7 (събота ден от седмицата) =12.. И така, знаем, че първата сряда ще бъде цялата седмица, така че най-ранната ще бъде be е 7-мо и 14-о число, за разлика от 1-во и 8-мо (най-ранното от месеца).

Сега, когато знаем КОГА е 2-та сряда от месеца, сравнете това с датата, на която изпълняваме заявката въз основа (т.е. curdate() ). Ако текущата дата е ВКЛЮЧЕНА или ПРЕДИ (чрез <=) ВТОРАТА СРЕДА на МЕСЕЦА (@SWOM), тогава искаме да пропуснем само 1 месец... ако сме по-нататък в месеца, трябва да пропуснем 2 месеца.

Сега изградете датите. Базата за дата за месец 1 е първият от текущия месец ПЛЮС интервал от толкова месеци, който трябва да се пропусне. Месец 2 е един месец след първия, месец 3 един след месец 2 и месец 4 един след месец 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 )

Така че най-накрая имаме всички 4-месечни бази, с които да работим в един ред (изберете ...) sqlvars набор от резултати, показващ нещо като

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

И накрая, след като тези данни изглеждат добре, вече можем да изградим конкретните низове, които търсите със съответните префикси "Q", "U", "V" и "X", плюс лявото 3 от името на месеца с 2 цифрена година.

Така че, като получите всички периоди от време и низове, които очаквате, потърсете това спрямо другата си таблица, както посочих в началото.

Надявам се това да ви помогне и да ви отвори очите за напълно нов контекст, за да подмамите SQL да... по същество правите вградена програма, за да създадете много променливи и да работите от това... Доста готино нали...

И честно казано, това е първият път, когато изпробвам специално тази техника, въпреки че в миналото съм правил много заявки с помощта на SQLVars.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Вземете маркери за mp4 файлове

  2. Табло за обяви - Оптимизация на база данни

  3. PHP и mySQL - написани като ë

  4. Как да затворя sqlalchemy връзка в MySQL

  5. как да попълним стойността на колоната на mysql въз основа на формула?