SQl中多使用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_nameNULL!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 ( '%', '红', '%' ) 
            ) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值