2

我正在尝试从表 A 中选择项目,其中表 B 中存在给定约束的等效项目。表 A 中的每个 id 有一行,但每个表 A 行有很多行。

select distinct A.id 
from A inner join B on B.a_id = A.id 
where B.x >= 5 and B.x <= 10;

我想知道是否有一个 SQL 连接子句可以用来确保每个表 A 行只有一行。

据我了解,查询将找到约束,执行内部联接,然后对此执行不同的。如果这是正确的,并且有更好的方法来指示数据库仅从 A 中获取不同的行,我想知道。我确信有很多方法可以在查询语义的约束下解释和执行查询。我不能声称理解explain输出。

有没有办法简化这个?如果这有什么不同,我会被限制在 SQLite 上。

编辑

约束子句有两个约束,在我现在添加的查询时定义。我试图让问题尽可能简单,但为了回应评论添加了额外的条款以确保完整性。

4

2 回答 2

3

这是编写查询的另一种方法:

select A.id
from A
where A.id in (select B.a_id from B where B.x > 5)

我不认为表现会更好,但它确实消除了外部“独特”。

我将在 MySQL 中使用另一个版本:

select A.id
from A
where exists (select 1 from B where b.x > 5 and b.a_id = a.id limit 1)

这可能更有效,因为查询可以使用索引查找并在第一次匹配时停止。如果您在 B 上有 (a_id, x) 的索引,则尤其如此。

于 2012-09-10T19:24:17.703 回答
1

如果FOREIGN KEY两个表之间存在(正确执行),则通过消除 table 将获得(轻微)效率增益A

SELECT DISTINCT a_id AS id
FROM B 
WHERE x >= 5 and x <= 10 ;

上的索引(a_id, x)似乎合适,但效率将取决于各种参数(多少百分比的 id 匹配条件x>5?有多少行具有相同的 id?等)。

我也会尝试这个查询(添加上述索引后):

SELECT a_id AS id
FROM B 
GROUP BY a_id
HAVING MAX(x) >= 5 
   AND MIN(x) <= 10 ;

当您也需要以下数据时,这将起作用A

SELECT A.* 
FROM A
  JOIN 
    ( SELECT a_id
      FROM B 
      GROUP BY a_id
      HAVING MAX(x) >= 5 
         AND MIN(x) <= 10  
    ) AS b
  ON b.a_id = a.id ;
于 2012-09-10T20:18:29.587 回答