我想知道是否有更好的方法来执行以下查询,或者是否有必要使其更好? (考虑到DB负载不是那么大)。唯一的标准是3个“变量”必须包含在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。
谢谢!
答案 0 :(得分:4)
试试这个:
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
答案 1 :(得分:1)
如果您想找到具有三个标签之一的候选人,您还可以使用条件聚合:
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"例如,标签。