SQL CASE语句,一个结果似乎无法访问

时间:2014-12-08 20:40:20

标签: sql sql-server tsql sql-server-2005 case

我试图通过我现在正在维护的大量数据库存储过程来解决问题,而且我遇到了令人困惑的问题。我无法判断它是否包含冗余/无用的代码,或者我是否遗漏了一些细微差别,因为我仍然只是SQL语言的中间人。这是相关代码部分:

UPDATE #NewValues
SET ValidNumber = CASE WHEN SP.ModelNumber IS NULL THEN 0
                            ELSE 1
                        END
FROM #NewValues NV
LEFT OUTER JOIN Stage.Products SP
    ON NV.SKU = SP.SKU
    AND (NV.ModelNumber = SP.ModelNumber OR NV.UPC = SP.ModelNumber)
WHERE NV.SKU IN (
    SELECT NV.SKU
    FROM #NewValues NV
    INNER JOIN Stage.Products SP
        ON NV.SKU = SP.SKU
        AND (NV.ModelNumber = SP.ModelNumber OR NV.UPC = SP.ModelNumber)
    WHERE NV.ValidNumber = 1
)

从实现这一点开始,在我看来似乎没有SP.ModelNumber将为NULL的情况,因为嵌套的SELECT语句永远不会返回带有SP.ModelNumber NULL结果的SKU 。所以唯一能做的就是SET ValidNumber = 1。那是对的吗?同样,我不确定这里是否还有其他东西我无法考虑到逻辑,但似乎嵌套的SELECT语句就是你需要的全部内容用来达到同样的效果。由于这个代码在一个更大的查询中的定位方式,我很难设置一个与正常使用相匹配的情况来测试它,特别是因为我不确定是什么此代码段运行之前,ValidNumber值将为

3 个答案:

答案 0 :(得分:2)

这取决于数据的性质。如果单个Sku可以在newvalues表中包含多个记录,则可能需要outer join,并且可以设置validnumber = 0


以下是一些试图说明的示例数据(如下所示):

create table newvalues (validnumber int, sku int, modelnumber int, upc int);
create table products (sku int, modelnumber int);

insert into newvalues values (1, 1, 1, 1), (0, 1, 1, 1), (null, 1, 2, 2);
insert into products values (1, 1);

如您所见,newvalues表中有多个结果sku = 1


然后是update声明:

UPDATE NewValues
SET validnumber = CASE WHEN SP.ModelNumber IS NULL THEN 0
                            ELSE 1
                        END
FROM NewValues NV
LEFT OUTER JOIN Products SP
    ON NV.SKU = SP.SKU
    AND (NV.ModelNumber = SP.ModelNumber OR NV.UPC = SP.ModelNumber)
WHERE NV.SKU IN (
    SELECT NV.SKU
    FROM NewValues NV
    INNER JOIN Products SP
        ON NV.SKU = SP.SKU
        AND (NV.ModelNumber = SP.ModelNumber OR NV.UPC = SP.ModelNumber)
    WHERE NV.ValidNumber = 1
);

这会更新所有行,有些行为0,有些为1,因为子查询中至少有一行存在inner join。这不会否定outer join,因为同一sku存在多行,因此它们都会更新(即使是那些sp.modelnumber is null

答案 1 :(得分:0)

原始编码器只是安全。 在Stage.Products中可能存在#NewValues中的项目,如果是这种情况,LEFT JOIN将导致SP中的所有字段在没有匹配的情况下为NULL。

答案 2 :(得分:0)

我可能会弄错,但你使用的是第一个WHERE

WHERE NV.SKU IN (
    SELECT NV.SKU
    FROM #NewValues NV
    INNER JOIN Stage.Products SP
        ON NV.SKU = SP.SKU
        AND (NV.ModelNumber = SP.ModelNumber OR NV.UPC = SP.ModelNumber)
    WHERE NV.ValidNumber = 1
)

你在这里做同样的JOIN,就像在上面一样。

我会选择:

UPDATE #NewValues
SET ValidNumber = CASE WHEN SP.ModelNumber IS NULL THEN 0
                        ELSE 1
                    END
FROM #NewValues NV
INNER JOIN Stage.Products SP
    ON NV.SKU = SP.SKU
    AND (NV.ModelNumber = SP.ModelNumber OR NV.UPC = SP.ModelNumber)
WHERE NV.ValidNumber = 1