Tôi đã tạo SQL Fiddle của giải pháp này để bạn chơi cùng.
Về cơ bản, nó tạo Bảng công việc @Months và sau đó Cross tham gia ý chí này vào tất cả các năm trong tập dữ liệu của bạn. Điều này tạo ra một danh sách đầy đủ của tất cả các tháng cho tất cả các năm. Sau đó, tôi rời tham gia dữ liệu Kiểm tra được cung cấp trong ví dụ của bạn (Bảng có tên TEST - xem SQL fiddle cho lược đồ) trở lại danh sách này để cung cấp cho tôi danh sách đầy đủ với Giá trị cho các tháng có chúng. Vấn đề tiếp theo cần khắc phục là sử dụng các giá trị của tháng trước nếu các tháng này không có giá trị nào. Đối với điều đó, tôi đã sử dụng một truy vấn phụ có tương quan, tức là chỉ kết hợp tblValues trở lại chính nó khi nó khớp với Xếp hạng tối đa của một hàng có một giá trị. Điều này sau đó cung cấp một tập hợp kết quả hoàn chỉnh!
Nếu bạn muốn lọc theo năm \ tháng, bạn có thể thêm điều này vào mệnh đề WHERE ngay trước mệnh lệnh Cuối cùng Theo.
Hãy tận hưởng!
Lược đồ kiểm tra
CREATE TABLE TEST( Month tinyint, Year int, Value int)
INSERT INTO TEST(Month, Year, Value)
VALUES
(1,2013,100),
(4,2013,101),
(8,2013,102),
(2,2014,103),
(4,2014,104)
Truy vấn
DECLARE @Months Table(Month tinyint)
Insert into @Months(Month)Values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
With tblValues as (
select Rank() Over (ORDER BY y.Year, m.Month) as [Rank],
m.Month,
y.Year,
t.Value
from @Months m
CROSS JOIN ( Select Distinct Year from Test ) y
LEFT JOIN Test t on t.Month = m.Month and t.Year = y.Year
)
Select t.Month, t.Year, COALESCE(t.Value, t1.Value) as Value
from tblValues t
left join tblValues t1 on t1.Rank = (
Select Max(tmax.Rank)
From tblValues tmax
Where tmax.Rank < t.Rank AND tmax.Value is not null)
Order by t.Year, t.Month