補充缺失日期及對應數據


數據庫環境:SQL SERVER 2008R2

  有一個數據表,只有2個字段,一個是日期字段,另一個是數據字段,其中,

日期字段的日期是不連續的。要求:補全日期,對應的數據為上一個日期的數據除於7。

  現有數據如圖1,

    圖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')
View Code

  實現

/*取得最小、最大日期*/
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
View Code

  實現的方法不止這一種,也有網友提供了另一種解法。

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
View Code

  我們還可以再升級一下需求,再計算結果的步驟,不再是除於固定值7,而是除於兩個日期

之間相差的天數。感興趣的朋友可以做下,就當練練手。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM