Mal*_*ist 35 sql t-sql sql-server
我有一个查询,我想作为子查询运行,将返回一组FK.有了它们,我想只返回具有匹配键的行.
SELECT ID
FROM tblTenantTransCode
WHERE
tblTenantTransCode.CheckbookCode =
(SELECT ID FROM tblCheckbookCode WHERE Description = 'Rent Income')
Run Code Online (Sandbox Code Playgroud)
这将返回所有具有与租金收入匹配的支票簿代码的交易代码
现在我想选择所有事务,其事务代码与子查询中返回的ID匹配.我已经做到这一点,但SQL Server抱怨语法错误.我怎样才能做到这一点?
SELECT *
FROM tblTransaction
WHERE
tblTransaction.TransactionCode IN
(SELECT ID FROM tblTenantTransCode
WHERE tblTenantTransCode.CheckbookCode =
(SELECT ID FROM tblCheckbookCode WHERE Description = 'Rent Income'))
Run Code Online (Sandbox Code Playgroud)
tblCheckbookCode
ID
Description
Other Info
tblTenantTransCode
ID
CheckbookCode <-- fk we're looking for
in the tblCheckbookCode.
We're selecting only checkbook codes
that have the Description 'Rent Income'
Other Info
tblTransactions
ID
TransactionCode <-- fk to tenant transaction code.
We're looking for an ID that is returned
in the above query/join
spe*_*593 66
要回答有关使用EXISTS关键字的问题,下面是一个使用EXISTS谓词的示例查询,该查询基于您问题中当前给出的查询.
SELECT t.*
FROM tblTransaction t
WHERE EXISTS
(
SELECT 1
FROM tblTenantTransCode ttc
JOIN tblCheckbookCode cc
ON (cc.ID = ttc.CheckbookCode AND cc.Description='Rent Income')
WHERE ttc.ID = t.TransactionCode
)
额外细节:
我们都认识到有各种SQL语句将返回满足指定要求的结果集.这些查询的观察性能可能会有所不同.性能尤其取决于DBMS,优化器模式,查询计划和统计信息(行数和数据值分布).
这样做的一个优点EXISTS是它清楚地表明我们不感兴趣从子查询中的表中返回任何表达式.它用于逻辑地将子查询与外部查询分开,其方式与a JOIN不相同.
使用的另一个优点EXISTS是,如果我们改为使用a,则避免返回可能(可能)返回的重复行JOIN.
一个EXISTS谓语可用于测试的子表的任何相关行的存在,而不需要加入.例如,以下查询返回一组包含至少一个关联line_item的所有订单:
SELECT o.*
FROM order o
WHERE EXISTS
( SELECT 1
FROM line_item li
WHERE li.order_id = o.id
)
请注意,子查询不需要查找所有匹配的行项,它只需要找到一行以满足条件.(如果我们将此查询编写为a JOIN,那么只要订单包含多个订单项,我们就会返回重复的行.)
一个NOT EXISTS谓语也是有用的,例如,返回一组做的订单不会有任何相关line_items.
SELECT o.*
FROM order o
WHERE NOT EXISTS
( SELECT 1
FROM line_item li
WHERE li.order_id = o.id
)
当然,NOT EXISTS只是一种选择.使用OUTER连接和IS NULL测试可以获得等效的结果集(假设我们在line_item表中至少有一个表达式是NOT NULL)
SELECT o.*
FROM order o
LEFT
JOIN line_item li ON (li.order_id = o.id)
WHERE li.id IS NULL
关于需要使用IN谓词或需要使用谓词,似乎有很多讨论(与原始问题的答案有关)JOIN.
这些结构是替代品,但不是必需的.查询可以返回所需的结果集,而无需使用IN和不使用JOIN.可以使用使用EXISTS谓词的查询返回结果集.(请注意,OP问题的标题确实询问了如何使用EXISTS关键字.)
这是另一个替代查询(这不是我的第一选择),但返回的结果集确实满足指定的要求:
SELECT t.*
FROM tblTransaction t
WHERE EXISTS
(
SELECT 1
FROM tblTenantTransCode ttc
WHERE ttc.ID = t.TransactionCode
AND EXISTS
(
SELECT 1
FROM tblCheckbookCode cc
WHERE cc.ID = ttc.CheckbookCode
AND cc.Description = 'Rent Income'
)
)
最重要的是,在给定所有可能的条件集的情况下,查询应返回正确的结果集,满足指定的要求.
在此处作为答案呈现的一些查询不返回请求的结果集,或者如果它们发生,则它们偶然发生.如果我们预先假设有关数据的某些内容,则某些查询将起作用,因此某些列是UNIQUE和NOT NULL.
性能差异
有时,带有EXISTS谓词的查询的执行效果不如带有谓词JOIN或IN谓词的查询 .在某些情况下,它可能表现更好.(对于EXISTS谓词,子查询只需找到一行满足条件,而不是找到所有匹配的行,如a所要求的那样JOIN.)
各种查询选项的性能最好通过观察来衡量.
您正在描述内部联接.
select tc.id
from tblTenantTransCode tc
inner join tblCheckbookCode cc on tc.CheckbookCode = cc.CheckbookCode
Run Code Online (Sandbox Code Playgroud)
编辑:它仍然是一个内部联接.我认为还没有任何理由使用IN子句.
select *
from tblTransaction t
inner join tblTenantTransCode tc on tc.id = t.TransactionCode
inner join tblCheckbookCode cc on cc.id = tc.CheckbookCode
where cc.description = 'Rent Income'
Run Code Online (Sandbox Code Playgroud)
编辑:如果必须使用EXISTS谓词来解决此问题,请参阅@ spencer7953的答案.然而,从我所看到的,上面的解决方案更简单,并且基于"子查询"为您工作的事实存在唯一性的假设(如果该表中没有唯一性,则不会100%的时间).我也在说
现在我想选择所有事务,其事务代码与子查询中返回的ID 匹配
在我的回答中.如果请求是这样的:
现在我想在任何事务代码与子查询中返回的ID匹配时选择All Transcations .
我会使用EXISTS查看子表中是否存在任何事务代码,并根据需要返回每一行或没有.