使用Window Function多条件删除表记录的问题求助
解决方案
原语句的问题
CASE语句缺少END,导致语法错误;- 窗口函数的逻辑不符合需求——你需要判断同
ProductCode下是否存在指定的FR43/FR44/FR45记录,而非统计所有非NL46的行数; - 多数数据库不允许在
DELETE的WHERE子句中直接使用窗口函数。
正确写法(兼容性最优)
用EXISTS子查询来实现需求,这是最通用的方式,几乎支持所有关系型数据库:
DELETE FROM MyTable WHERE ShopCode = 'NL46' AND EXISTS ( SELECT 1 FROM MyTable t2 WHERE t2.ProductCode = MyTable.ProductCode AND t2.ShopCode IN ('FR43', 'FR44', 'FR45') )
这个语句的逻辑:仅删除ShopCode为NL46的行,且仅当该ProductCode下存在目标FR开头的ShopCode记录时才执行删除,完全匹配你的需求。
窗口函数实现方式(部分数据库支持)
如果想用窗口函数,可以通过CTE(公共表表达式)先计算每个ProductCode是否存在目标ShopCode,再执行删除:
WITH ProductCheck AS ( SELECT *, MAX(CASE WHEN ShopCode IN ('FR43', 'FR44', 'FR45') THEN 1 ELSE 0 END) OVER (PARTITION BY ProductCode) AS HasTargetShop FROM MyTable ) DELETE FROM ProductCheck WHERE ShopCode = 'NL46' AND HasTargetShop = 1;
注意:不同数据库的CTE删除语法略有差异,比如MySQL需要调整为:
WITH ProductCheck AS ( SELECT *, MAX(CASE WHEN ShopCode IN ('FR43', 'FR44', 'FR45') THEN 1 ELSE 0 END) OVER (PARTITION BY ProductCode) AS HasTargetShop FROM MyTable ) DELETE t FROM ProductCheck t WHERE t.ShopCode = 'NL46' AND t.HasTargetShop = 1;
关于其他ShopCode的处理
你的需求仅涉及删除特定条件的NL46行,其他ShopCode的记录不会被上述语句修改,全部保留,无需额外处理。
内容的提问来源于stack exchange,提问作者RebeccaJohnson
相关产品推荐
相关产品推荐

