[英]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.