检查子查询结果中是否有任何值


8

我有一个复杂的子查询,该查询返回订单ID列表。我需要获得拥有这些订单的客户列表。问题是有两种将客户分配给订单的方式(两个字段之一)。我可以做这样的事情:

 select *
 from Customers
 where orderId in (select...) 
 or secondaryOrderId in (select ...)

问题在于,子查询在执行时间和屏幕空间上都是巨大的。有没有一种方法可以检查其中一个字段是否包含所需结果之一?

Answers:


10

尝试:

where exists (select * .... 
        where Customers.orderId = ... 
        or Customers.secondaryId = ...
     )

例如,如果您计划:

where orderId in (select value from ...)
or secondaryorderid in (select value from ...)

然后进行创建,以便仅调用一次子查询,并在其中构建OR子句。

 where exists (select * from ... 
        where Customers.orderId = value 
        or Customers.secondaryOrderId = value
     )

这样做的全部目的是确保复杂的子查询仅执行一次。对于CTE或用两个EXISTS替换两个IN都不会发生这种情况。


3

您的查询可能应该改写为exists而不是in

有关更多示例,请参见此链接

然后,您的查询看起来与

select *
from Customers C
where exists (select 'x' from ordertable o where c.orderid = o.orderid) 
or exists (select 'x' from ordertable o where c.secondaryOrderId = o.orderid) 

如果两个子查询相同,则可以删除其中的一个并合并它们

select *
from Customers C
where exists (select 'x' from ordertable o where c.orderid = o.orderid or c.secondaryOrderId = o.orderid) 

2

为什么不使用Common Table Expression aka with子句?它正是为此目的(以及其他目的)而设计的。

with orderIds as (
  select orderId
  from ...
)
select *
from Customers
where orderId in (select orderId from orderIds) 
or secondaryOrderId in (select orderId from orderIds);

请参阅https://msdn.microsoft.com/zh-cn/library/ms175972%28v=sql.105%29.aspx以获取Microsoft的文档。


3
就所花费的时间而言,这样做并没有太大的好处。CTE不会被缓存,并且将在两次引用时执行。stackoverflow.com/questions/22041244/...
马克Sinkinson

1
好。似乎每个DBMS处理CTE的方式都不同。
Colin't Hart 2015年

CTE不是为此目的而设计的。它仍然会两次扩展到主查询中。尝试看看...
Rob Farley

1
微软的文档误导了“ [CTE]可以看作是一个临时结果集”,我将其解释为意味着结果被缓存或像临时表一样存储。现在,还没有提到另一个T-SQL解决方案。
Colin't Hart

@ Colin'tHart欢迎使用Microsoft文档:-)
Mark Sinkinson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.