说我有以下架构:
create table foo (
foo_id int not null,
name text not null,
primary key (foo_id)
);
create table bar (
bar_id int not null,
foo_id int not null,
index int not null,
value text not null,
primary key (bar_id),
foreign key (foo_id) references foo (foo_id)
);
foo
和bar
之间的一对多关系; foo
是bar
的有序容器。
如何有效搜索foo
包含某组bar
s的记录?也就是说,如果我有一个bar.value
的列表,那么foo
对于每个bar
都有一个关联的bar
?
请注意,我需要存储有关exists
s顺序的信息,但希望在搜索时忽略排序。
我能想到的唯一方法是:
bar
子查询以编程方式为我感兴趣的每个值编写查询select
f.*
from
foo f
where
exists (select 1 from bar b where b.foo_id = f.foo_id and value = 'value 1') and
exists (select 1 from bar b where b.foo_id = f.foo_id and value = 'value 2') and
...
exists (select 1 from bar b where b.foo_id = f.foo_id and value = 'value n')
编写内部联接的查询例如:
select
f.*
from
foo f,
bar b1,
bar b2,
...
bar bn
where
b1.foo_id = f.foo_id and b1.value = 'value 1' and
b2.foo_id = f.foo_id and b2.value = 'value 2' and
...
bn.foo_id = f.foo_id and bn.value = 'value n'
根据您需要匹配的值动态构建。
可替换地:
{{1}}
有没有更好的方法在SQL中实现这一点?
我可以使用其他架构来简化这项工作吗?
答案 0 :(得分:1)
我认为存在的技术是最好的。但如果你想以不同的方式做到这一点,也许这就是:
with x as (
select f.id
from foo f
join bar b
on b.foo_id = f.id
where b.value in ('value 1', 'value 2', ..., 'value n')
group by f.id
having count(distinct b.value)) = n
)
select f.*
from foo f
join x.id = f.id
如果我的语法错误,你将不得不原谅我。我没有建立一个数据库来测试我的答案。
我知道有些人不喜欢使用CTE,所以这里有另一种选择:
select f.*
from (
select f.id
from foo f
join bar b
on b.foo_id = f.id
where b.value in ('value 1', 'value 2', ..., 'value n')
group by f.id
having count(distinct b.value)) = n
) x
join foo f on f.id = x.id
答案 1 :(得分:0)
除非我在这里遗漏了一些内容,否则这两个表格之间看起来就像一个简单的Join
。
如何有效地搜索包含特定条形图的foo记录?也就是说,如果我有一个bar.values列表,那些foos每个都有一个关联的栏?
您可以使用以下内容找到与foo
值相关联的bar
:
Select Distinct f.foo_id, f.name
From bar b
Inner Join foo f On f.foo_id = b.foo_id
Where b.value In ('your', 'search', 'values')