SQl中多使用EXISTS导致多查出了一条不符合条件的数据
摘要:本文分析了SQL查询中出现NULL值被意外检索的问题。原查询通过LIKE和EXISTS子句查找包含"红"字的记录,却返回了compose_name为NULL的数据。排查发现,聚合子查询(string_agg)和EXISTS子查询的过滤条件不一致:前者包含了merchant_id、yxbz、strike_out等条件,而后者缺少这些限制,导致EXISTS可能匹配到被聚合丢弃
原本的部分条件如下
and i.is_complement = '20'
and i.yxbz = '1'
AND (
i.name LIKE concat ('%', '红', '%')
OR EXISTS (
SELECT
*
FROM
commodity_suit_compose csc
WHERE
csc.suit_id = i.ID
AND csc.compose_name LIKE concat ('%', '红', '%')
)
)
查寻 i 表的name 和 csc 表中的compose_name,含有"红"这个字的数据,但是查出了一条compose_name不含红字且为空的数据
发现这条 compose_name 是 NULL!null明明不包含"红" 但是为什么null会被查出来呢,
原本我以为是 compose_name 为 NULL,有些数据库(尤其某些兼容性模式开启时)会 不严格排除 NULL 值条件失效的情况,导致 EXISTS 子查询仍返回了记录 → 主记录被错误保留。
但后面我加了 is not null的条件还是能查出来,但是大概能猜到问题出在EXISTS里面
,最后发现是聚合子查询和EXISTS里面的查询过滤不一致导致的,
我的聚合子查询是这样写的
(
SELECT
string_agg ( compose_name, ',' )
FROM
(
SELECT
compose_name
FROM
commodity_suit_compose csc
WHERE
csc.suit_id = i.ID
AND csc.merchant_id = i.merchant_id
AND csc.yxbz = '1'
AND csc.strike_out = '0'
ORDER BY
csc.num DESC
) AS sorted_names
) "compose_name"
EXISTS是这样写的
EXISTS (
SELECT
*
FROM
commodity_suit_compose csc
WHERE
csc.suit_id = i.ID
AND csc.compose_name LIKE concat ( '%', '红', '%' )
)
-
聚合(string_agg) 和 判断存在(EXISTS) 必须在同一个“数据子集”上做过滤,才能保证逻辑一致。
-
在聚合时只看了“同商家、上架、未删除”的行,却在
EXISTS里忘了这几条,导致EXISTS能拿到一些“被聚合丢掉”的行。 -
最后给EXISTS加上相同的过滤条件即可
-
EXISTS (
SELECT
*
FROM
commodity_suit_compose csc
WHERE
csc.suit_id = i.ID
AND csc.merchant_id = i.merchant_id
AND csc.yxbz = '1'
AND csc.strike_out = '0'
AND csc.compose_name LIKE concat ( '%', '红', '%' )
)
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)