由于一段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}}
答案 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
子句正在过滤以下任一项为真的记录:
.
deleted_at IS NULL和twitter_user_tags
。tag_id
IN(' 3',' 6',' 8&# 39;,' 12').
deleted_at IS NULL和twitter_status_tags
。tag_id
IN(' 3',' 6',' 8&# 39;,' 12')此查询中的过滤记录也是您的3个内部联接。内部联接仅返回表之间的匹配记录,您希望使用OUTER
联接以避免过度过滤。
此外,表别名对于使代码更易于阅读非常有用。