有什么方法可以替代 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" 个标签,则需要此版本。
我想知道下面的查询是否有更好的方法或者是否有必要改进? (考虑到数据库负载不是那么大)。唯一的标准是 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" 个标签,则需要此版本。