基于商品为各店铺添加标识的Oracle SQL实现问题
解决店铺商品标识字段的正确SQL实现
原语句的问题分析
- 语法错误:CASE语句结构不符合SQL规范,多个判断条件必须通过独立的
WHEN子句定义,原语句在第一个THEN后直接用AND连接新条件,会导致语法报错。 - 逻辑偏差:
row_number() over(partition by a.product, a.shop ...)是对每个「商品-店铺」组合单独编号,每个分组仅返回1条数据,无法判断整个店铺的商品集合,因此无法识别店铺是否同时包含商品A和B。
正确实现方案
方案一:先聚合店铺商品,再关联回原表
通过CTE先统计每个店铺的商品覆盖情况,再关联原表为每条商品记录添加标识:
WITH shop_product_summary AS ( SELECT shop, BOOL_OR(product = 'a') AS has_product_a, BOOL_OR(product = 'b') AS has_product_b FROM data GROUP BY shop ) SELECT d.product, d.shop, CASE WHEN sps.has_product_a AND sps.has_product_b THEN 'contains product A & B' WHEN sps.has_product_a THEN 'contains product A' -- 可根据需求扩展其他商品的判断逻辑 ELSE 'other' END AS FLAG FROM data d JOIN shop_product_summary sps ON d.shop = sps.shop;
方案二:使用窗口函数直接判断
无需额外聚合,通过窗口函数在店铺维度统计商品存在情况,直接生成标识:
SELECT product, shop, CASE WHEN MAX(CASE WHEN product = 'a' THEN 1 ELSE 0 END) OVER (PARTITION BY shop) = 1 AND MAX(CASE WHEN product = 'b' THEN 1 ELSE 0 END) OVER (PARTITION BY shop) = 1 THEN 'contains product A & B' WHEN MAX(CASE WHEN product = 'a' THEN 1 ELSE 0 END) OVER (PARTITION BY shop) = 1 THEN 'contains product A' ELSE 'other' END AS FLAG FROM data;
方案说明
- 方案一适合需要复用店铺商品统计结果的场景,大数据量下性能更稳定。
- 方案二更简洁,无需额外CTE,直接通过窗口函数完成全量数据的标识计算。
内容的提问来源于stack exchange,提问作者lowstrife
相关产品推荐
相关产品推荐

