clientId clientPassword
1 1234
2 1234
3 1234
表B中选择行得到查询
clientId clientCode
1 TRN
2 ABC
3 CDE
3 TRN
会是怎样的查询与只有那些clientID的选择TableA.clientPassword TableB.clientCode中没有'TRN'?
作为复杂查询的一部分,但被简化为可以解答我的问题。
clientId clientPassword
1 1234
2 1234
3 1234
表B中选择行得到查询
clientId clientCode
1 TRN
2 ABC
3 CDE
3 TRN
会是怎样的查询与只有那些clientID的选择TableA.clientPassword TableB.clientCode中没有'TRN'?
作为复杂查询的一部分,但被简化为可以解答我的问题。
这是一个基本的not exists
;
select a.*
from tableA a
where not exists (select 1
from tableB b
where a.clientId = b.clientId and b.clientcode = 'TRN'
);
这里更多 - https://technet.microsoft.com/en-us/library/ms184297(v=sql.105).aspx
不存在完美的作品是写这个逻辑上直接的方式,但并不总是最高效的选择。使用一个不依赖于数据库系统的算法可以将查询平坦化,以避免逐行运行。有了这个简单的查询,数据库系统可能会弄清楚,但你可以把它写成扁平的方式。
SELECT a.*
FROM TableA a LEFT JOIN TableB b ON a.clientId = b.clientid
AND b.clientcode = 'TRN'
WHERE b.ClientId IS NULL
为了解释这一点的左连接将加入B表对表A,其中ID的比赛和clientcode是“TRN”,但将保持在表格中的所有条目,并具有表B中的NULL当记录'TRN'不存在,所以那么空检查就等同于另一个查询中不存在,但是避免逐行检查相关的子查询并且应该快得多。
有趣的变化!谢谢埃文。 – Dev
*必须为每行单独运行*:不正确。没有规则将SQL实现限制为特定的*方式来执行某些操作。事实上,大多数DBMS在可行的情况下会将相关子查询“变平”。如果您在您的DBMS中找到两个逻辑上等效的最小查询的示例,其中相关子查询的执行与外部联接显着不同,但没有记录,我建议您提交问题报告。这不是一个错误,但它是一个优化机会。 –
@ JamesK.Lowden我编辑了我的帖子以使其软化并允许查询的DBMS优化。 –