我正在尝试为以下场景构建查询:
我有两个表 Table1 和 Table2 。
Table1 的主键如 T1Attr1 , T1Attr2 等等。
对应于 Table1 中的每个主键,我可以从 Table2 获取一组属性,类似于 T2Attr1 , T2Attr2 等等。
我正在尝试查询 Table1 属性所共有的属性,例如,如果输入是 T1Attr1 和 T1Attr2 ,结果应具有 Table2 的两个共同属性。随着输入参数的增加,结果会更少,因为普通的属性会更少。
我的查询与此类似:
Select indId, indName from indData where pId =1
intersect
Select indId, indName from indData where pId =2
intersect
Select indId, indName from indData where pId =3
查询工作正常但是当pId列表很大(大于100)时,jdbc驱动程序会抛出错误消息。
有人可以提供有关正确使用此查询的建议,还是提供更好的解决方法?
谢谢!
答案 0 :(得分:3)
您可以使用此查询,但效率不如您所拥有的那样:
SELECT indId, indName
FROM indData
WHERE pId IN (1, 2, 3, ..., 100)
GROUP BY indId, indName
HAVING COUNT(DISTINCT pId) = 100 ; -- the number of pId you are searching on
您也可以使用JOINs
。也许这将导致更好的执行计划,而不会导致此错误。如果(indId, pId)
上存在唯一约束,则这相当于您的查询:
SELECT a1.indId, a1.indName
FROM indData AS a1
JOIN indData AS a2
ON a2.indId = a1.indId
JOIN indData AS a3
ON a3.indId = a1.indId
...
JOIN indData AS a100
ON a100.indId = a1.indId
WHERE a1.pId = 1
AND a2.pId = 2
...
AND a100.pId = 100 ;
(pId, indID) INCLUDE (indName)
上的索引有助于提高效率。
答案 1 :(得分:2)
Intersect
不是做你想做的事的唯一方法。您的查询是“set-within-sets”查询的示例。 “set”是indid, indname
对。 “内部集合”具有pid
的所有三个值。
我提倡对这种类型的查询使用带有having
子句的聚合,因为对于许多类型的条件,这是一种非常灵活的方法。在您的情况下,结果查询是:
select indid, indname
from indData
group by indid, indname
having SUM(case when pid = 1 then 1 else 0 end) > 0 and
SUM(case when pid = 2 then 1 else 0 end) > 0 and
SUM(case when pid = 3 then 1 else 0 end) > 0;
如果您在pid
上有索引并且值相对较少,那么添加where pid in (1, 2, 3)
可能会使查询在性能方面受益。