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


8

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

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

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

回答:


10

試してください:

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で置き換えることでも発生しません。


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) 

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

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);

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


3
時間がかかるという点で、これを実行してもあまりメリットはありません。CTEはキャッシュされず、参照される両方のときに実行されます。stackoverflow.com/questions/22041244/...
マーク・Sinkinson

1
OK。各DBMSがCTEを異なる方法で処理しているようです。
Colin 't Hart

CTEはこの目的のために設計されていません。それでもメインクエリに2回展開されます。試してみる...
Rob Farley、

1
また、Microsoftのドキュメントは誤解を招く「[A CTE]は一時的な結果セットと見なすことができる」と誤解しており、結果が一時テーブルのようにキャッシュされるか、そうでなければ保存されることを意味すると解釈しました。現在、まだ言及されていない別のT-SQLソリューションがあります。
Colin 't Hart

@ Colin'tHart Microsoftドキュメントの世界へようこそ:-)
Mark Sinkinson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.