web-dev-qa-db-ja.com

いずれかの値がサブクエリの結果に含まれているかどうかを確認します

注文IDのリストを返す複雑なサブクエリがあります。これらの注文がある顧客のリストを取得する必要があります。問題は、顧客を注文に割り当てる方法が2つあることです(2つのフィールドのうちの1つ)。私はこのようなことをすることができます:

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

問題は、サブクエリが実行にかかる時間と画面スペースの両方で非常に大きいことです。フィールドのoneに目的の結果が含まれているかどうかを確認する方法はありますか?

8
user63844

試してください:

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

たとえば、以下を計画している場合:

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

次に、サブクエリを1回だけ呼び出すように作成し、OR句をその中に組み込みます。

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

これの要点は、複雑なサブクエリが1回だけ実行されるようにすることです。これは、CTEでは発生せず、2つのINを2つのEXISTSで置き換えることでも発生しません。

10
Rob Farley

クエリはおそらく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) 

両方のサブクエリが同じである場合、それらの1つを削除してそれらを組み合わせることができます

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

コモンテーブル式(別名with句)を使用しないのはなぜですか?それは(とりわけ)まさにこの目的のために設計されています。

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

Microsoftのドキュメントについては、 https://msdn.Microsoft.com/en-us/library/ms175972%28v=sql.105%29.aspx を参照してください。

2
Colin 't Hart