Dibutuhkan banyak pra-pemeriksaan, tetapi pada dasarnya, saya harus membangun variabel SQL berdasarkan satu langkah pada satu waktu, seolah-olah dalam program "biarkan X =sesuatu", "biarkan y =X + sesuatu yang lain" , dll. Dengan membangun variabel @SQLVars paling dalam, setelah yang pertama dideklarasikan, variabel tersebut dapat digunakan sebagai basis dari variabel berikutnya dan seterusnya... Pertama, inilah kueri lengkap yang dapat Anda terapkan pada data yang dibangun berdasarkan tanggal apa pun saat ini. Anda yang mengetahui data Anda lebih baik mungkin harus mengubahnya, tetapi saya pikir ini akan membantu Anda.
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
Hasil dari satu kueri di atas akan mengembalikan catatan TUNGGAL (berdasarkan tanggal saat ini 31 Jan) untuk ditampilkanBulan PertamaBulan KeduaBulan KetigaBulan KeempatQ (12 Mar) U (12 Apr) V (12 Mei) X (12 Jun)
Sekarang, susun ini di dalam sisa kueri Anda untuk ID ticker Anda seperti
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()
Jika Anda melihat @SqlVariables terdalam seperti yang disebutkan sebelumnya adalah seperti sekelompok "biarkan x =sesuatu". Saya selalu membutuhkan dasar untuk memulai, jadi saya pertama-tama memasukkan hari pertama bulan tertentu ke dalam variabel @FirstOfMonth dengan melakukan penggabungan tahun berapa pun dari tanggal saat ini + "-" + bulan dari tanggal saat ini + "-01" untuk selalu dimulai pada awal bulan... mis:Hari ini 31 Jan 2012 akan membangun string '2012-01-01' yang dalam format tahun/bulan/tanggal langsung dikenali oleh MySQL sebagai format tanggal kita dapat melakukan aritmatika tanggal. Jadi sekarang, saya punya @FirstOfMonth ='2012-01-01'. Sekarang, kita perlu menentukan Hari pertama dalam seminggu, tanggal ini mewakili bulan kita berada (karenanya @FDOW). Ini akan mengembalikan nilai dari 1-7 (Minggu =1, Rab =4, Sab =7).
Dari sini, kita sekarang perlu menghitung kapan Rabu ke-2 setiap bulannya. Jika hari dalam seminggu adalah Minggu sampai (dan termasuk) Rabu, Rabu KEDUA adalah 12 hari MINUS hari dalam seminggu. Contoh:Minggu tanggal 1 adalah Rabu tanggal 4, kemudian Rabu tanggal 11... jadi 12 - 1 (Minggu) =11. Jika hari pertama bulan itu adalah Rabu, itu akan menjadi hari dalam seminggu =4, tetapi 1 bulan =Rab, Rab kedua =8, jadi 12 - 4 =8. Sekarang, jika tanggalnya adalah Kam, Jum atau Sab sebagai awal bulan, Hari dalam seminggu adalah 5, 6 atau 7 MINIMUM Tanggal Rabu pertama adalah 7, Rabu kedua adalah 14, jadi ini dimulai dengan 19 - hari apa pun dalam seminggu... 5, 6, 7... Contoh:19 - 5(Kamis Hari Minggu) =14, 19 - 6(Jumat Hari Minggu) =13, 19 - 7(Sabtu Hari Minggu) =12.. Jadi, kita tahu bahwa Rabu pertama akan menjadi minggu penuh, jadi paling awal akan be adalah tanggal 7 dan 14 sebagai lawan dari tanggal 1 dan 8 (awal bulan).
Sekarang kita tahu KAPAN Rabu ke-2 setiap bulan, bandingkan dengan tanggal kita menjalankan kueri berdasarkan (yaitu:curdate() ). Jika tanggal saat ini AKTIF atau SEBELUM (via <=) RABU KEDUA BULAN (@SWOM), maka kita hanya ingin melewati 1 bulan... jika kita lebih jauh di bulan itu, kita perlu melewati 2 bulan.
Sekarang, buat tanggalnya. Dasar tanggal untuk Bulan 1 adalah yang pertama dari bulan berjalan PLUS interval berapa pun bulan yang harus dilewati. Bulan 2 adalah satu bulan melewati yang pertama, Bulan 3 satu melewati Bulan 2, dan Bulan 4 satu melewati Bulan 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 )
Jadi kami akhirnya memiliki dasar 4 bulan untuk bekerja dalam satu baris ( pilih ... ) kumpulan hasil sqlvars yang menunjukkan sesuatu seperti
@Month1 @Month2 @Month3 @Month4
2012-03-01 2012-04-01 2012-05-01 2012-06-01 ... the four months out
Akhirnya, setelah data ini muncul, kita sekarang dapat membuat string spesifik yang Anda cari dengan awalan "Q", "U", "V" dan "X" masing-masing ditambah 3 kiri nama bulan dengan 2 tahun digit.
Jadi, dengan ini mendapatkan semua rentang tanggal dan string yang Anda harapkan, kueri ini terhadap tabel Anda yang lain seperti yang saya cantumkan di awal.
Saya harap ini membantu Anda dan membuka mata Anda ke konteks yang benar-benar baru untuk mengelabui SQL ke... pada intinya melakukan program sebaris untuk membuat banyak variabel dan mengoperasikannya... Cukup keren ya...
Dan sejujurnya, ini adalah pertama kalinya saya secara khusus mencoba teknik ini, meskipun saya telah melakukan banyak pertanyaan di masa lalu menggunakan SQLVars.