Phải kiểm tra trước rất nhiều, nhưng về bản chất, tôi phải xây dựng các biến SQL dựa trên từng bước một, như thể nó nằm trong chương trình "let X =something", "let y =X + somethingelse" , v.v. Bằng cách xây dựng các biến @SQLVars bên trong nhất, khi biến đầu tiên được khai báo, nó có thể được sử dụng làm cơ sở cho biến tiếp theo, v.v. Trước tiên, đây là truy vấn đầy đủ mà bạn có thể áp dụng cho dữ liệu của mình. dựa trên bất kể ngày hiện tại là gì. Bạn hiểu rõ dữ liệu của mình hơn có thể phải chỉnh sửa một số, nhưng tôi nghĩ điều này sẽ giúp bạn tốt trên con đường của mình.
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
Kết quả của một truy vấn ở trên sẽ trả về một bản ghi DUY NHẤT (dựa trên ngày hiện tại là ngày 31 tháng 1) cho showFirstMonth SecondMonth ThirdMonth FourMonthQ (Mar 12) U (12 tháng 4) V (12 tháng 5) X (12 tháng 6)
Bây giờ, hãy lồng cái này vào bên trong phần còn lại của truy vấn cho các ID mã của bạn giống như
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()
Nếu bạn nhìn vào @SqlVariables trong cùng như đã đề cập trước đó giống như một loạt "let x =something". Tôi luôn cần cơ sở để bắt đầu, vì vậy trước tiên tôi chuyển ngày đầu tiên của một tháng nhất định vào một biến @FirstOfMonth bằng cách ghép bất kỳ năm nào với ngày hiện tại + "-" + tháng của ngày hiện tại + "-01" luôn bắt đầu vào đầu tháng ... ví dụ:Hôm nay là ngày 31 tháng 1 năm 2012 sẽ tạo ra một chuỗi '2012-01-01' ở định dạng năm / tháng / ngày được MySQL nhận ra ngay lập tức như một định dạng ngày, chúng ta có thể thực hiện số học ngày. Vì vậy, bây giờ, tôi có @FirstOfMonth ='2012-01-01'. Bây giờ, chúng ta cần xác định Ngày đầu tiên trong tuần, ngày này đại diện cho tháng chúng ta đang ở (do đó @FDOW). Điều này sẽ trả về giá trị từ 1-7 (Chủ nhật =1, T4 =4, T7 =7).
Từ điều này, bây giờ chúng ta cần tính toán khi nào sẽ là Thứ Tư thứ 2 của tháng. Nếu ngày trong tuần là Chủ Nhật đến (và bao gồm cả) Thứ Tư, thì Thứ Tư THỨ HAI là 12 ngày TRỪ một ngày trong tuần. Ví dụ:Chủ nhật ngày 1 sẽ là Thứ 4, sau đó Thứ 4 là 11 ... do đó 12 - 1 (Chủ nhật) =11. Nếu ngày đầu tiên của tháng LÀ Thứ 4, nó sẽ là một ngày trong tuần =4, nhưng Ngày đầu tiên của tháng =Thứ tư, Thứ tư thứ hai =8, vì vậy 12 - 4 =8. Bây giờ, nếu ngày đầu tiên của tháng là Thứ năm, Thứ sáu hoặc Thứ bảy, thì Ngày trong tuần sẽ là ngày 5, 6 hoặc 7 . Ngày TỐI THIỂU của Thứ Tư đầu tiên sẽ là 7, Thứ Tư thứ hai sẽ là 14, vì vậy điều này sẽ bắt đầu bằng 19 - bất kỳ ngày nào trong tuần ... 5, 6, 7 ... Ví dụ:19 - 5 (Thứ Tư ngày Tuần) =14, 19 - 6 (Ngày thứ Sáu trong tuần) =13, 19 - 7 (Ngày thứ Bảy trong tuần) =12 .. Vì vậy, chúng tôi biết rằng Thứ Tư đầu tiên sẽ là cả tuần kết thúc, vì vậy, sớm nhất sẽ là be là thứ 7 và 14 so với ngày 1 và 8 (sớm nhất trong tháng).
Bây giờ chúng ta đã biết KHI NÀO ngày Thứ Tư thứ 2 của tháng, hãy so sánh ngày đó với ngày chúng ta đang chạy truy vấn dựa trên (ví dụ:curdate ()). Nếu ngày hiện tại BẬT hoặc TRƯỚC (qua <=) NGÀY THỨ HAI CỦA THÁNG (@SWOM), thì chúng ta chỉ muốn bỏ qua hơn 1 tháng ... nếu xa hơn trong tháng, chúng ta cần bỏ qua 2 tháng.
Bây giờ, hãy xác định ngày tháng. Cơ sở ngày cho Tháng 1 là ngày đầu tiên của tháng hiện tại CỘNG phải bỏ qua một khoảng thời gian bao nhiêu tháng. Tháng 2 cách tháng đầu tiên một tháng, Tháng 3 trước Tháng 2 và Tháng 4 trước Tháng 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 )
Vì vậy, cuối cùng chúng tôi có tất cả cơ sở 4 tháng để làm việc với một hàng (chọn ...) tập kết quả sqlvars hiển thị một cái gì đó như
@Month1 @Month2 @Month3 @Month4
2012-03-01 2012-04-01 2012-05-01 2012-06-01 ... the four months out
Cuối cùng, khi dữ liệu này xuất hiện ổn, bây giờ chúng tôi có thể xây dựng các chuỗi cụ thể mà bạn đang tìm kiếm với các tiền tố "Q", "U", "V" và "X" tương ứng cộng với 3 bên trái của tên tháng với 2 năm chữ số.
Vì vậy, với việc này nhận được tất cả các phạm vi ngày và chuỗi mà bạn đang mong đợi, hãy truy vấn điều này dựa trên bảng khác của bạn như tôi đã liệt kê trong phần đầu.
Tôi hy vọng điều này sẽ giúp ích cho bạn và giúp bạn mở ra một bối cảnh hoàn toàn mới để đánh lừa SQL ... về bản chất là thực hiện một chương trình nội tuyến để tạo nhiều biến và hoạt động từ đó ... Khá tuyệt phải không ...
Và thành thật mà nói, đây là lần đầu tiên tôi đặc biệt thử kỹ thuật này, mặc dù trước đây tôi đã thực hiện nhiều truy vấn bằng SQLVars.