2017-01-12 60 views
3

有一些問題與主義查詢生成器,而不是在聲明Doctrine2的QueryBuilder NOT IN語句不工作

我有表有四列和一些數據:

id | directory_id| user_id | role_id 

1 1    10  null 
2 1    5  null 
3 1    null 1 
4 1    7  null 

我想要選擇的是所有領域不在兩個給定的ID數組內。

$userIds = [10, 5]; 
$roleIds = [1]; 

我的查詢:

$this->createQueryBuilder('da') 
    ->where('da.directory = :directory') 
    ->andWhere('da.user NOT IN (:userIds)') 
    ->andWhere('da.role NOT IN (:roleIds)') 
    ->setParameters([ 
     'directory' => $directory, 
     'userIds' => $userIds, 
     'roleIds' => $roleIds, 
     ]) 
     ->getQuery() 
     ->getResult(); 

按照我的理解,它應該返回我的最後一排(#ID 4),但事實並非如此。

也許有人知道什麼是錯的?

+3

對於NULL,NOT IN有點棘手。如果返回NULL,則NOT IN將變爲false,並且不返回任何行。這就是爲什麼我通常不會相反。 – jarlh

回答

2

不幸的是,與NULL值的比較總是會導致UNKNOWN這是一個虛假值。
已經在你的第四行執行的語句如下:

(1 <> 10 AND 1 <> 5) AND (NULL <> 1) 

導致下面,是一個falsy結果

(TRUE AND TRUE) AND (UNKNOWN) 

要測試你必須使用IS NULLNULL值或IS NOT NULL。以下查詢應該可以工作:

$this->createQueryBuilder('da') 
    ->where('da.directory = :directory') 
    ->andWhere('(da.user NOT IN (:userIds) OR da.user IS NULL)') 
    ->andWhere('(da.role NOT IN (:roleIds) OR da.role IS NULL)') 
    ->setParameters([ 
     'directory' => $directory, 
     'userIds' => $userIds, 
     'roleIds' => $roleIds, 
    ]) 
    ->getQuery() 
    ->getResult();