[英]Most efficient SQL for this example
Table A: Person: id, name
Table B: Toys: id, person_id, toy_name
我有一个搜索屏幕,其中包含固定玩具名称的下拉列表。 如果匹配一个人的玩具的总子集,则会找到一个搜索。
例如,一个人名字=鲍勃的人有玩具:洋娃娃,汽车,房子,帽子
搜索人员姓名=鲍勃,玩具=娃娃,帽子。
我想退回鲍勃和他所有的玩具,而不仅仅是寻找的玩具(娃娃,帽子)。 发现鲍勃是因为他的玩具的一部分是火柴。
我不知道最有效/最少的数据库调用该方法的方式。 我可以搜索bob并获取所有他的玩具,然后解析结果集以查看搜索到的玩具是否找到了匹配项,但这似乎是错误的,db调用可能会返回未找到匹配项的行(似乎错了吗?)。
好的,
select
p.id,
p.name,
t.id as toyid,
t.toy_name
from
person p
join
toys t
on p.id = t.person_id
where
p.id in (
select person_id from toys where toy_name = 'doll'
intersect
select person_id from toys where toy_name = 'hat');
如果您进一步规范化架构,
create table Person
(
Id int,
Name varchar(100)
);
create table Toy
(
Id int,
Name varchar(100)
);
create table PersonToy
(
Id int,
PersonId int,
ToyId int
);
它应该使问题的复杂性更加清晰。 它还将节省一些空间。 形式的声明,
select
p.Name PersonName,
t.Name ToyName
from
Person p
join
PersonToy pt
on pt.PersonId = p.Id
join
Toy t
on t.Id = pt.ToyId
where
p.Id in
(
select PersonId from PersonToy where ToyId = 1
intersect
select PersonId from PersonToy where ToyId = 4
);
将有效地工作。
这是使用子查询并检查HAVING
子句中Hat和Doll是否存在的一种方法:
select p.id, p.name,
t.id as toyid, t.name as toyname
from person p
inner join toys t on p.id = t.person_id
inner join (
select person_id
from toys
group by person_id
having sum(name = 'hat') > 0 and
sum(name = 'doll') > 0
) t2 on p.id = t2.person_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.