带有 INSERT 的 CTE 有时会执行两次声明

CTE with INSERT does the statement twice, sometimes

我有一个 CTE,可以拆分记录、计算天数、生成 ID 以及 historicLicMed 上的许多其他内容用于报告,要求专门要求定期存储 CTE 的结果 table。为此,我将 CTE 改编为对这个新的 table 有一个 INSERT into,问题是由于某种原因,插入在先前拆分的记录 上执行了两次 ,这导致新的 table 存储大约原始记录量的 3 倍(从 30k 到 80k,当没有插入的 cte 导致 50k-ish 记录时)。

原文中的示例数据table:

ID  IDHIST   INI      END      DD
--- ------- -------- -------- ---
1   x       20180101 20180205 36

cte 本身的作用以及应该粘贴到新的 table:

ID  IDHIST   INI      END      DD
--- ------- -------- -------- --
1   x       20180101 20180131 31
2   x       20180202 20180205 5

带插入件的 cte 的作用:

ID  IDHIST   INI      END      DD
--- ------- -------- -------- --
1   x       20180101 20180131 31
2   x       20180202 20180205 5
3   x       20180101 20180131 31
4   x       20180202 20180205 5

这是整个 cte,对 INSERT 语句中的任何帮助都表示赞赏。

;WITH N(N) AS 
    (
    SELECT ROW_NUMBER() OVER (ORDER BY [object_id])-1 FROM SYS.ALL_COLUMNS
    ),
    D(N,F,T,MD,BP,EP,
    --COLUMNAS TABLA ORIGINAL HISTORICOLICMED
    VALIDO,IDHIST,ID_HR,TIPO,ID_TIPO,NOM_INC,RUT,NOMBRE,ID_EMP,NOM_POS,DIAS_DURAC,INI,FIN,NUM_LIC,ID_USU_ACT,ULT_ACT) AS  
    (
        SELECT n.N,d.INI,d.FIN,
            DATEDIFF(MONTH, d.INI, d.FIN),
            DATEADD(MONTH, n.N, DATEADD(DAY, 1-DAY(INI), INI)),
            DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(MONTH, n.N, 
            DATEADD(DAY, 1-DAY(INI), INI)))),
            --COLUMNAS TABLA ORIGINAL
            D.VALIDO,D.IDHIST,D.ID_HR,D.TIPO,D.ID_TIPO,D.NOM_INC,D.RUT,D.NOMBRE,D.ID_EMP,D.NOM_POS,D.DIAS_DURAC,D.INI,D.FIN,D.NUM_LIC,D.ID_USU_ACT,D.ULT_ACT
        FROM N INNER JOIN HISTORICOLICMED AS D
        ON d.FIN >= DATEADD(MONTH, n.N-1, d.INI)
    ), E AS (
        SELECT VALIDO,IDHIST,ID_HR,TIPO,ID_TIPO,NOM_INC,RUT,NOMBRE,ID_EMP,NOM_POS,INI,FIN,NUM_LIC,ID_USU_ACT,ULT_ACT, --dias_durac
        --columnas originales INI / FIN
        CONVERT(NVARCHAR(10),f, 103) as original_INI, CONVERT(NVARCHAR(10),t, 103) as original_FIN, DIAS_DURAC,
        --columnas con ampliación
        CONVERT(NVARCHAR(10), CASE n WHEN 0 THEN f ELSE bp END,103) AS nuevo_INI,
        --new_INI = CASE n WHEN 0 THEN f ELSE bp END,
        CONVERT(NVARCHAR(10), CASE n WHEN md THEN t ELSE ep END,103) AS nuevo_FIN
        --new_INI = CASE n WHEN md THEN t ELSE bp END
        FROM D
        WHERE MD >= N
    ), I AS (
        SELECT E.*, 
                DATEDIFF(DD, NUEVO_INI,NUEVO_FIN)+1 as DIAS_DURAC2, 
                CONVERT(nvarchar(6),CAST(nuevo_ini as datetime),112) as PERPRO
        FROM E --ORDER BY IDHIST 
    )
    INSERT INTO DBO.HISTORICOLICMEDPROC 
    (VALIDO,IDHIST,ID_HR,TIPO,ID_TIPO,NOM_INC,RUT,NOMBRE,ID_EMP,NOM_POS,INI,FIN,NUM_LIC,ID_USU_ACT,ULT_ACT,ORIGINAL_INI,ORIGINAL_FIN,DIAS_DURAC,NUEVO_INI,NUEVO_FIN,DIAS_DURAC2,PERPRO)
    SELECT E.VALIDO,E.IDHIST,E.ID_HR,E.TIPO,E.ID_TIPO,E.NOM_INC,E.RUT,E.NOMBRE,E.ID_EMP,E.NOM_POS,E.INI,E.FIN,E.NUM_LIC,E.ID_USU_ACT,E.ULT_ACT,E.ORIGINAL_INI,E.ORIGINAL_FIN,E.DIAS_DURAC,E.NUEVO_INI,E.NUEVO_FIN,I.DIAS_DURAC2,I.PERPRO
    FROM E LEFT JOIN I ON E.IDHIST = I.IDHIST
GO

是连接出了问题,只调用了最后一个 table 并重命名了最后 2 个变量,这样我就可以一次性调用所有内容。

SELECT E.VALIDO,E.IDHIST,E.ID_HR,E.TIPO,E.ID_TIPO,E.NOM_INC,E.RUT,E.NOMBRE,E.ID_EMP,E.NOM_POS,E.INI,E.FIN,E.NUM_LIC,E.ID_USU_ACT,E.ULT_ACT,E.ORIGINAL_INI,E.ORIGINAL_FIN,E.DIAS_DURAC,E.NUEVO_INI,E.NUEVO_FIN,E.DIAS_DURAC2,E.PERPRO
    FROM I AS E