如何插入依赖于多列sql的缺失数字

时间:2015-09-29 02:10:04

标签: sql sql-server

所以我有这样的表:

img

你可以看到的是我有一个缺少的月份数,即1。 我想要的是在我的表中插入一个这样的值:

Month  Year  Col1        Forecast   Customer
1      2015  HD/FB/BK/      0          AFC

因为这是一个缺失的月份,所以我希望预测为0值。

此插入的参数将按年份,col1和客户。

2 个答案:

答案 0 :(得分:1)

首先,根据您的参数生成所有月 - 月组合的行。然后使用NOT EXISTS插入缺失的行:

DECLARE @yr         INT,
        @col1       VARCHAR(50),
        @customer   VARCHAR(50);

WITH Cte(mnt, yr, col1, customer) AS(
    SELECT *, @yr, @col1, @customer
    FROM(VALUES
        (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)
    )t(N)
)
INSERT INTO tbl(Month, Year, Col1, Forecast, Customer)
    SELECT
        mnt,
        yr,
        col1,
        0,
        customer
    FROM Cte c
    WHERE
        NOT EXISTS(
            SELECT 1 
            FROM tbl
            WHERE
                Col1 = c.col1
                AND Customer = c.customer
                AND Month = c.mnt
                AND Year = c.yr
        )

答案 1 :(得分:0)

此处的方法是生成monthcol1的组合,并与当前表匹配,并为缺失的行生成插入。您可以使用customeryear的其他所需组合对此进行扩展。如果特定组合没有单一条目,这种方法很有效。

步骤1:创建组合表

SELECT 
    *
FROM
    (SELECT 1 month UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) months
        JOIN
    (SELECT 'HD/FB/BK' colname UNION ALL SELECT 'HD/FB/BL') col1

第2步:查找缺少的项目

select expected.* from data_table dt right join (SELECT 
    *
FROM
    (SELECT 1 month UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) months
        JOIN
    (SELECT 'HD/FB/BK' colname UNION ALL SELECT 'HD/FB/BL') col1) expected on (dt.month = expected.month and dt.Col1 = expected.colname) where dt.col1 is null

步骤3:插入缺失值(全部合并)

insert into data_table
select datainsert.month, 2015, datainsert.colname, 0.0, 'AFC' FROM
(select expected.* from data_table dt right join (SELECT 
    *
FROM
    (SELECT 1 month UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) months
        JOIN
    (SELECT 'HD/FB/BK' colname UNION ALL SELECT 'HD/FB/BL') col1) expected on (dt.month = expected.month and dt.Col1 = expected.colname) where dt.col1 is null) datainsert;