數據庫環境:SQL SERVER 2008R2
有一個數據表,只有2個字段,一個是日期字段,另一個是數據字段,其中,
日期字段的日期是不連續的。要求:補全日期,對應的數據為上一個日期的數據除於7。
現有數據如圖1,
實現的效果如圖2(數據太多,已省略部分)
實現思路:
1.用數字輔助表補全缺失的日期
2.將當前開始補錄日期到下一個補錄日期之間的日期視為一組,不包括下一個補錄日期
3.分析函數求得分組內的最大數據,並計算結果
建表,導入測試數據

CREATE TABLE test(cdate DATE,num NUMERIC(6,2)) INSERT INTO test VALUES ('2015-10-03','21') INSERT INTO test VALUES ('2015-10-10','49') INSERT INTO test VALUES ('2015-10-17','147') INSERT INTO test VALUES ('2015-10-24','63')
實現

/*取得最小、最大日期*/ WITH x0 AS ( SELECT MIN(cdate) AS date_begin , MAX(cdate) AS date_end FROM test ),/*生成最小、最大日期之間的所有日期*/ x1 AS ( SELECT DATEADD(DAY, number, date_begin) AS cdate , number AS rn FROM x0 CROSS APPLY master..spt_values sv WHERE sv.type = 'P' AND sv.number <= DATEDIFF(DAY, date_begin, date_end) ),/*和原表左連接,取到num*/ x2 AS ( SELECT x1.cdate , t.num , rn , CASE WHEN t.num IS NOT NULL THEN 1 ELSE 0 END AS gp FROM x1 LEFT JOIN test t ON t.cdate = x1.cdate ),/*生成分組依據*/ x3 AS ( SELECT cdate , num , ( SELECT SUM(gp) FROM x2 x WHERE x.rn <= x2.rn ) AS gp FROM x2 )/*計算結果*/ SELECT cdate , CASE WHEN num IS NOT NULL THEN num ELSE MAX(num / 7) OVER ( PARTITION BY gp ) END AS num FROM x3
實現的方法不止這一種,也有網友提供了另一種解法。

WITH tmp AS ( SELECT DATEADD(d, number, '2015-10-03') d , number % 7 number FROM master..spt_values WHERE type = 'P' AND DATEADD(d, number, '2015-10-03') <= '2015-10-24' ) SELECT d , CASE WHEN tmp1.cdate IS NULL THEN t.num / 7 ELSE tmp1.num END AS num FROM tmp LEFT JOIN test tmp1 ON tmp.d = tmp1.cdate OUTER APPLY ( SELECT TOP 1 * FROM test tmp1 WHERE tmp.d > cdate ORDER BY cdate DESC ) t
我們還可以再升級一下需求,再計算結果的步驟,不再是除於固定值7,而是除於兩個日期
之間相差的天數。感興趣的朋友可以做下,就當練練手。