You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多AND/OR运算符SQL转Doctrine DQL的正确性验证求助

你的DQL查询与原SQL不一致,问题及修正方案如下

首先看你的原SQL逻辑:

SELECT *
FROM table
-- [other WHERE CONDITIONS]
WHERE (field-A = 2 AND field-B IS NULL) OR (field-A = 2 AND field-B IS NULL);

这个条件其实等价于 field-A = 2 AND field-B IS NULL(两个完全相同的条件用OR连接没有实际意义),但先分析你写的QueryBuilder代码存在的问题:

现有代码的问题

  1. 方法调用错误:isNull('t.field-A') 没有调用QueryBuilder的实例方法,正确写法应为 $qb->isNull('t.field-A')
  2. 逻辑分组错误:你当前的链式写法未给AND条件添加分组括号,Doctrine会按运算符优先级(AND > OR)拼接逻辑,最终生成的DQL是:
    t.field-A IS NULL AND t.field-B = :data OR t.field-A = :data AND t.field-B IS NULL
    
    这和原SQL逻辑完全不符——原SQL是两个相同的(field-A=2 AND field-B IS NULL)用OR连接,而你的代码实际表达的是**(field-A为空且field-B等于data) 或者 (field-A等于data且field-B为空)**。

正确的QueryBuilder写法

如果你确实需要原SQL的逻辑(重复OR条件,可简化)

$qb = $this->createQueryBuilder('t');
// 先添加其他WHERE条件
// ...

// 简化后的条件(等价于原SQL的重复OR逻辑)
$qb->andWhere('t.field-A = :data AND t.field-B IS NULL')
   ->setParameter('data', $data);

如果是笔误,实际想表达两个不同的组合条件(比如(field-A=:data AND field-B IS NULL) OR (field-A IS NULL AND field-B=:data))

可以用子QueryBuilder的表达式API明确分组条件:

$qb = $this->createQueryBuilder('t');
// 先添加其他WHERE条件
// ...

$qb->andWhere(function ($subQb) use ($data) {
    // 第一个分组条件:field-A等于data 且 field-B为空
    $condition1 = $subQb->expr()->andX(
        $subQb->expr()->eq('t.field-A', ':data'),
        $subQb->expr()->isNull('t.field-B')
    );
    // 第二个分组条件:field-A为空 且 field-B等于data
    $condition2 = $subQb->expr()->andX(
        $subQb->expr()->isNull('t.field-A'),
        $subQb->expr()->eq('t.field-B', ':data')
    );
    // 用OR连接两个分组条件
    $subQb->where($subQb->expr()->orX($condition1, $condition2));
    $subQb->setParameter('data', $data);
});

或者用更直观的字符串写法(注意手动添加分组括号):

$qb = $this->createQueryBuilder('t');
// 先添加其他WHERE条件
// ...

$qb->andWhere('(t.field-A = :data AND t.field-B IS NULL) OR (t.field-A IS NULL AND t.field-B = :data)')
   ->setParameter('data', $data);

内容的提问来源于stack exchange,提问作者Flys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 13:35:11