我有2个表,它们之间可以有多对多的关系:
Person (pid, name, a,b) ,
Attributes (attribId, d,e)
映射存在于单独的表中:
Mapping (mapId, pid, attribId)
目标是获取符合过滤条件的人员的所有人员和属性值。筛选条件基于“属性”表中的列。例如 - 列d。
例如:
Person ->
(1,'person1','a1','b1')
(2,'person2','a1','b1')
Attributes ->
(1,'d1','e1')
(2,'d2','e1')
(3,'d3','e1')
(4,'d3','e2')
Mapping ->
(1,1,1)
(2,1,2)
(3,1,3)
After running the query ->
Result:
(1,'person1','a1','b1')(1,'d1','e1')
(1,'person1','a1','b1')(2,'d2','e1')
(1,'person1','a1','b1')(3,'d3','e1')
查询我一直在尝试 - >
select p.*, a.*
from
Person p
left outer join
Mapping m
on p.pid=m.pid
left outer join
Attributes a
on m.attribId=a.attribId
where
p.pid in (select p1.pid
from
Person p1
left outer join
Mapping m1
on p1.pid=m1.pid
left outer join
Attributes a1
on m1.attribId=a1.attribId
where
a1.d = 'd1')
同样,我还必须丢弃具有特定d值的Person条目。
因此,目前,最终查询如下所示:
SELECT
p.*,
a.*
FROM Person p
LEFT OUTER JOIN Mapping m
ON p.pid = m.pid
LEFT OUTER JOIN Attributes a
ON m.attribId = a.attribId
WHERE p.pid IN (SELECT
p1.pid
FROM Person p1
LEFT OUTER JOIN Mapping m1
ON p1.pid = m1.pid
LEFT OUTER JOIN Attributes a1
ON m1.attribId = a1.attribId
WHERE a1.d = 'd1')
AND p.pid NOT IN (SELECT
p2.pid
FROM Person p2
LEFT OUTER JOIN Mapping m2
ON p2.pid = m2.pid
LEFT OUTER JOIN Attributes a2
ON m2.attribId = a2.attribId
WHERE a2.d = 'd5');
感觉这个查询效率很低,因为在3个地方完成了相同的连接。有没有办法重用所有子查询的连接并使其更有效?
答案 0 :(得分:2)
您可以使用以下方式让所有人满意过滤器:
z{1} to z{4}
您可以使用select m.pid
from mapping m join
attributes a
on m.attribId = a.attribId and a.d = 'dS';
或IN
或EXISTS
获取所有人/属性组合。哪个更好取决于数据库。但这个想法是:
JOIN
我认为没有理由让这些查询select p.*, a.*
from person p join
mapping m
on p.pid = m.pid join
attributes a
on m.attribId = a.attribId
where p.pid in (select m.pid
from mapping m join
attributes a
on m.attribId = a.attribId and a.d = 'dS'
);
。
编辑:
如果过滤条件基于多个列,则使用left join
和group by
作为子查询:
having
答案 1 :(得分:1)
我注意到的第一件事是你在子查询中使用左连接,内连接也可以工作并且速度更快。其次从嵌套选择中删除Person,因为它不需要。
select m2.pid
from
Mapping m2
inner join
Attributes a2
on m2.attribId=a2.attribId
where
a2.d = 'd5'
答案 2 :(得分:0)
我们也可以做这样的事情
{{1}}
我知道有关于连接与子查询的讨论,但在这种情况下,我认为子查询会更快。