MySQL查询中的双WHERE IN OR执行AND而不是OR

时间:2014-05-23 21:28:19

标签: mysql sql laravel laravel-4 where-in

由于一段laravel代码,我有以下MySQL查询。我试图通过分析生成的查询来确定代码失败的位置。

查询应该选择twitter_status_tags twitter_user_tags中有tag_id的所有twitter_statuses,但是当前它会返回twitter_status_tags中有tag_id的所有twitter_statuses twitter_user_tags 1}} AND SELECT * FROM `project_twitter_statuses` INNER JOIN `twitter_statuses` ON `twitter_statuses`.`id` = `project_twitter_statuses`.`twitter_status_id` INNER JOIN `twitter_user_tags` ON `twitter_user_tags`.`twitter_user_id` = `twitter_statuses`.`twitter_user_id` INNER JOIN `twitter_status_tags` ON `twitter_status_tags`.`twitter_status_id` = `twitter_statuses`.`id` WHERE `project_twitter_statuses`.`deleted_at` IS NULL AND ( `twitter_user_tags`.`tag_id` IN ( '3', '6', '8', '12' ) OR `twitter_status_tags`.`tag_id` IN ( '3', '6', '8', '12' ) ) GROUP BY `twitter_statuses`.`id` ORDER BY `twitter_statuses`.`datetime` ASC;

据我所知,下面的查询是针对OR的,但是MySQL认为不然。

$projectTwitterStatuses = ProjectTwitterStatus::join('twitter_statuses','twitter_statuses.id','=','project_twitter_statuses.twitter_status_id');

// Tags
if(!empty($tagsSelectedArray)) {
    $projectTwitterStatuses = $projectTwitterStatuses
        ->join('twitter_user_tags','twitter_user_tags.twitter_user_id','=','twitter_statuses.twitter_user_id')
        ->join('twitter_status_tags','twitter_status_tags.twitter_status_id','=','twitter_statuses.id')
        ->where(function($query) use ($tagsSelectedArray)
        {
            $query->orWhereIn('twitter_user_tags.tag_id',$tagsSelectedArray)
                  ->orWhereIn('twitter_status_tags.tag_id',$tagsSelectedArray);
        })
        ->groupBy('twitter_statuses.id');
}

$projectTwitterStatuses = $projectTwitterStatuses->orderBy('twitter_statuses.datetime')
    ->paginate(10);

对于那些感兴趣的人,这是我的laravel应用程序中的代码

{{1}}

2 个答案:

答案 0 :(得分:0)

两个标记表上的内部联接给你一个和的效果,你希望外部联接得到无,两者都是

SELECT * 
FROM  `project_twitter_statuses` 
INNER JOIN  `twitter_statuses` ON  `twitter_statuses`.`id` =  `project_twitter_statuses`.`twitter_status_id` 
Left JOIN  `twitter_user_tags` ON  `twitter_user_tags`.`twitter_user_id` =  `twitter_statuses`.`twitter_user_id` 
Left JOIN  `twitter_status_tags` ON  `twitter_status_tags`.`twitter_status_id` =  `twitter_statuses`.`id` 
WHERE  `project_twitter_statuses`.`deleted_at` IS NULL 
AND (
`twitter_user_tags`.`tag_id` 
IN (
'3',  '6',  '8',  '12'
)
OR  `twitter_status_tags`.`tag_id` 
IN (
'3',  '6',  '8',  '12'
)
)
GROUP BY  `twitter_statuses`.`id` 
ORDER BY  `twitter_statuses`.`datetime` ASC;

添加此

Where (`twitter_user_tags`.`twitter_user_id` is not null) Or
      (`twitter_status_tags`.`twitter_status_id` is not null) 

会删除不存在标记的记录。

答案 1 :(得分:0)

WHERE子句正在过滤以下任一项为真的记录:

  • project_twitter_statuses . deleted_at IS NULL和twitter_user_tagstag_id IN(' 3',' 6',' 8&# 39;,' 12')
  • project_twitter_statuses . deleted_at IS NULL和twitter_status_tagstag_id IN(' 3',' 6',' 8&# 39;,' 12')

此查询中的过滤记录也是您的3个内部联接。内部联接仅返回表之间的匹配记录,您希望使用OUTER联接以避免过度过滤。

此外,表别名对于使代码更易于阅读非常有用。