我的数据库中有以下表格:
Month|Year | Value
1 |2013 | 100
4 |2013 | 101
8 |2013 | 102
2 |2014 | 103
4 |2014 | 104
如何从数据中填写“缺失”行,以便在2013-03至2014-03期间查询时,我会得到:
Month|Year | Value
3 |2013 | 100
4 |2013 | 101
5 |2013 | 101
6 |2013 | 101
7 |2013 | 101
8 |2013 | 102
9 |2013 | 102
10 |2013 | 102
11 |2013 | 102
12 |2013 | 102
1 |2014 | 102
2 |2014 | 103
3 |2014 | 103
正如您所看到的,我想重复之前的Value
以查找缺失的行。
答案 0 :(得分:5)
我已经为您创建了SQL Fiddle此解决方案。
基本上,它会创建一个工作表@Months,然后Cross会在数据集中连接这一年。这将生成所有年份所有月份的完整列表。然后,我将您的示例中提供的测试数据(名为TEST的表 - 请参阅模式的SQL小提琴)添加回此列表,以便为我提供包含具有它们的月份的值的完整列表。要解决的下一个问题是使用过去几个月的值,如果这几个月没有。为此,我使用了一个相关的子查询,即只有在匹配具有值的行的最大Rank时才将tblValues连接回自身。然后,这将给出一个完整的结果集!
如果您想按年/月过滤,可以在最终的Order By之前将其添加到WHERE子句中。
享受!
测试架构
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)
<强>查询强>
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