繁体   English   中英

有没有更有效的方法来编写此SQL查询以删除不重复项?

[英]Is there a more efficient way to write this SQL Query to remove the distinct?

我正在尝试从表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中获取不同的行。 我敢肯定,可以在查询语义的约束范围内解释和执行查询的方法有很多。 我不能声称理解explain输出。

有没有一种方法可以简化此过程? 如果这有任何区别,我将仅限于SQLite。

编辑

约束子句有两个约束,在查询时定义了这些约束,我现在添加了它们。 我试图使问题尽可能简单,但是为了回应评论,添加了多余的子句以保持完整性。

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

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)

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

如果两个表之间有一个(正确执行的) FOREIGN KEY ,则通过消除表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 ;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM