我在表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