sql - UPDATE 中的 CASE 会产生意想不到的结果。移至 WHERE 子句时已修复。为什么?
问题描述
我创建了一个查询来更新标志,我使用 CASE 语句来确定值。但是,当我将查询作为 UPDATE 语句运行时,只有大约一半的预期行被更新?更有趣的是,我之前对相同的数据运行了完全相同的 UPDATE 查询,并且它按预期工作(查看旧与新是导致我调查的原因)。
我尝试使用相同的 CASE 语句进行 SELECT 查询,我得到了正确的结果,但是将其切换回 UPDATE 只会更新大约一半的记录。
将条件移至 WHERE 子句解决了该问题。似乎是 SET 部分中的 CASE 语句导致了问题。我想不通为什么?我想知道这样可以避免将来我犯的任何错误。
原始代码:
UPDATE D
SET PUBLISH_FLAG =
CASE WHEN
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
THEN 'Y'
ELSE 'N'
END
FROM TBL_DATA D
INNER JOIN TBL_PUBLISH V
ON D.ID = V.ID
AND D.CENSUS_DATE = V.CENSUS_DATE
AND D.VERSION_NUMBER = V.VERSION_NUMBER
LEFT JOIN TBL_CAT_MAP C
ON D.SRC_CATEGORY = C.SOURCE_CAT
工作代码:
UPDATE D
SET PUBLISH_FLAG = 'Y'
FROM TBL_DATA D
INNER JOIN TBL_PUBLISH V
ON D.ID = V.ID
AND D.CENSUS_DATE = V.CENSUS_DATE
AND D.VERSION_NUMBER = V.VERSION_NUMBER
LEFT JOIN TBL_CAT_MAP C
ON D.SRC_CATEGORY = C.SOURCE_CAT
WHERE
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
我认为两者都应该产生完全相同的结果?我错过了什么?
为了帮助澄清下面的代码有 2 个显示差异,“PUBLISH_FLAG”列(使用我的原始代码或 PSK 的答案更新)有 10162 个“Y”值(其余的“N”),pub_2 列有正确的 18917' Y' 值。
SELECT
PUBLISH_FLAG,
CASE WHEN
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
THEN 'Y'
ELSE 'N'
END as pub_2
FROM TBL_DATA D
INNER JOIN TBL_PUBLISH V
ON D.ID = V.ID
AND D.CENSUS_DATE = V.CENSUS_DATE
AND D.VERSION_NUMBER = V.VERSION_NUMBER
LEFT JOIN TBL_CAT_MAP C
ON D.SRC_CATEGORY = C.SOURCE_CAT
WHERE
CASE WHEN
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
THEN 'Y'
ELSE 'N'
END = 'Y'
解决方案
两个查询都不相同,在第一个查询中,switch case 中所有不匹配的记录将被设置为 ' N
',而不管它们的当前状态如何。
对于仅更新所需记录的此类场景,第二个查询是正确的方法。
您可以更改您的第一个查询,如下所示,以避免更改不匹配的记录。
UPDATE D
SET PUBLISH_FLAG =
CASE WHEN
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
THEN 'Y'
ELSE PUBLISH_FLAG --Modified
END
FROM TBL_DATA D
INNER JOIN TBL_PUBLISH V
ON D.ID = V.ID
AND D.CENSUS_DATE = V.CENSUS_DATE
AND D.VERSION_NUMBER = V.VERSION_NUMBER
LEFT JOIN TBL_CAT_MAP C
ON D.SRC_CATEGORY = C.SOURCE_CAT
注意:在上面的查询中,我更改了 else 部分。
推荐阅读
- php - 第二个summernote在laravel中返回null
- python - 如何使用使用 keras 的训练模型获得预测值?
- mysql - 未能延迟初始化角色集合:
无法初始化代理 - 没有会话 - java - 为什么方法中的局部变量会提前被垃圾收集?
- reactjs - 如何解决反应组件中变量的未定义值?
- c++ - 如何打开图像天气是 TIFF、JPG 和 PNG 以及如何在 Visual C++ 中显示它?
- excel - 如何使用 OR 条件过滤 For 循环?
- ios - Xcode 11.1 似乎打破了 com.apple.commcenter.coretelephony.xpc
- angular - 从 Angular 4.2 更新到 Angular 9.0 + Jhipster
- malware - 如何从 Cuckoo Sandbox VM 中提取特定文件?