有什么方法可以替代 left join 还是有必要?

Any way to substitute left join or it is necessary?

我想知道下面的查询是否有更好的方法或者是否有必要改进? (考虑到数据库负载不是那么大)。唯一的标准是 3 "variables" 必须包含为 AND,并且查询可以有或多或少的 LEFT JOINS。

select `candidates`.* from `candidates` 
inner join `candidate_tag` on `candidates`.`id` = `candidate_tag`.`candidate_id` 
left join `tags` t1 on `t1`.`id` = `candidate_tag`.`tag_id` and t1.name like '%foo%'
left join `tags` t2 on `t2`.`id` = `candidate_tag`.`tag_id` and t2.name like '%baz%'
left join `tags` t3 on `t3`.`id` = `candidate_tag`.`tag_id` and t3.name like '%zoo%'
group by candidates.id
order by `candidates`.`last_name` asc

我的第一个镜头是使用 AND 运算符的条件查询,但它没有给我任何结果,所以这就是为什么我选择将其更改为 left join s.

谢谢!

试试这个:

select `candidates`.id from `candidates` 
inner join `candidate_tag` on `candidates`.`id` = `candidate_tag`.`candidate_id` 
inner join `tags` t on `t`.`id` = `candidate_tag`.`tag_id`
group by candidates.id
HAVING SUM(CASE WHEN t.tag_name LIKE '%foo%' THEN 1 ELSE 0 END) >= 1 AND SUM(CASE WHEN t.tag_name LIKE '%bar%' THEN 1 ELSE 0 END) >= 1 AND SUM(CASE WHEN t.tag_name LIKE '%aaa%' THEN 1 ELSE 0 END) >= 1
order by `candidates`.`last_name` asc

如果你想找到具有三个标签之一的候选人,你也可以使用条件聚合:

select c.*
from candidates c join
     candidate_tag ct
     on ct.candidate_id = c.id join
     tags t
     on ct.tag_id = t.id
where t.name like '%foo%' or
      t.name like '%baz%' or
      t.name like '%zoo%'
group by c.id
order by c.`last_name` asc;

您还可以添加group_concat(t.name) as tags来获取候选人匹配的标签。或者,如果您只想要所有三个都具备的候选人,您可以添加一个 having 子句:

having count(distinct t.name) = 3

having (max(t.name like '%foo%') +
        max(t.name like '%baz%') +
        max(t.name like '%zoo%')) = 3

例如,如果有太多 "foo" 个标签,则需要此版本。