我在表A(列ID
和DESC
)和B(列FK_ID
,CODE
)之间有一对多的关系。 ID
- >FK_ID
。在连接表中选择值和非值的有效SQL
我很想知道如何找到最有效的SQL来选择A中的所有行,其中B中有一个名为'C1'的代码,但在名为'N1'的B中有NOT
代码。
任何帮助表示赞赏。
我在表A(列ID
和DESC
)和B(列FK_ID
,CODE
)之间有一对多的关系。 ID
- >FK_ID
。在连接表中选择值和非值的有效SQL
我很想知道如何找到最有效的SQL来选择A中的所有行,其中B中有一个名为'C1'的代码,但在名为'N1'的B中有NOT
代码。
任何帮助表示赞赏。
使用EXISTS
和NOT EXISTS
会给予最佳性能
SELECT tableA.*
FROM tableA
WHERE
EXISTS(
SELECT NULL
FROM TableB
WHERE tableA.ID = TableB.FK_ID AND TableB.Code = 'C1')
AND NOT EXISTS(
SELECT NULL
FROM TableB
WHERE tableA.ID = TableB.FK_ID AND TableB.Code = 'N1')
我的理解(请纠正我,如果我错了)就是你有两个表所示:
create table A(ID int not null primary key, "DESC" varchar(30));
create table B(FK_ID int not null references A (ID), CODE varchar(30));
那么像这样的工作:
select
ta.*
from
A as ta
inner join
B as tb
on tb.FK_ID = ta.ID
where
tb.CODE = 'C1'
and not exists (select null from B as tb2 where tb2.FK_ID = ta.ID and tb2.CODE = 'N1')
选择A中的所有行,其中B中有一个名为'C1'的代码,但B中没有名为'N1'的代码。
我怀疑你的规范没有准确地传达你实际需要的东西!
字面解释将是
if there exists a row in B where CODE = 'C1'
and there does not exist a row in B where CODE = 'B1'
then return all rows from A
(即,存在于A和B分别的值之间没有相关性) 例如
SELECT *
FROM A
WHERE EXISTS (
SELECT *
FROM B
WHERE CODE = 'B1'
)
AND NOT EXISTS (
SELECT *
FROM B
WHERE CODE = 'C1'
);
然而,经验(单独)告诉我们,你可能想使用A.ID = B.FK_ID
关联的表。请参阅Magnus对一种方法的回答。
注意这里提到的存在和非存在的操作符分别被称为semi join和semi difference,它们可以用不同的方式写入SQL。从性能的角度来看,效率最高的将取决于许多变量,包括SQL引擎,数据,索引,统计数据等。您将需要使用典型数据进行测试。还要考虑到可读性和易维护性也是重要的因素。
此候选查询(或类似的东西)是可能是值得考虑的,如果你选择的SQL产品支持减号来EXCEPT
(在Oracle中实际调用MINUS
):
SELECT *
FROM A
WHERE ID IN (
SELECT FK_ID
FROM B
WHERE CODE = 'B1'
EXCEPT
SELECT FK_ID
FROM B
WHERE CODE = 'C1'
);
RDBMS是什么? SQL Server? MySQL的?甲骨文? – JNK 2012-01-16 18:22:57