0

我正在尝试为以下场景构建查询:

我有两个表Table1Table2

Table1的主键类似于T1Attr1T1Attr2等。

对应于Table1中的每个主键,我可以从Table2中获取一组属性,例如T2Attr1T2Attr2等。

我正在尝试查询Table1的属性共有的属性,例如,如果输入是T1Attr1T1Attr2 ,则结果应该具有来自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 驱动程序会抛出错误消息。

有人可以提供有关正确使用此查询的建议或为该问题提供更好的方法吗?

谢谢!

4

2 回答 2

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)将有助于提高效率。

于 2013-07-01T19:38:38.260 回答
2

Intersect不是做你想做的事的唯一方法。您的查询是“set-within-sets”查询的一个示例。“集合”是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并且值相对较少,那么添加 awhere pid in (1, 2, 3)可能会有益于查询性能。

于 2013-07-01T19:35:00.630 回答