-1

次のクエリについて考えてみます。ここでは、両方のセットを同じでフィルタリングする必要がありますLocation。フィルタが両方のセットに1回だけ適用される、より効率的でパフォーマンスの高いアプローチはありLocationますか、それとも各セットに同じフィルタを個別に適用する必要がありますか?

SELECT *
FROM   Orders
WHERE  Quantity BETWEEN 1 AND 100
AND Location = 'SE'

EXCEPT

SELECT *
FROM   Orders
WHERE  Quantity BETWEEN 50 AND 75
AND Location = 'SE';

注:セット操作自体をリファクタリングすることは考えていません。これは単なるダミーの例です。私の質問は、セット操作全体で共通のWHERE句をどのように処理するかについてのみです。

4

6 に答える 6

4

クエリを単純に次のようにリファクタリングします。

SELECT *
FROM Orders
WHERE Quantity BETWEEN 1 AND 100
AND Quantity NOT BETWEEN 50 AND 75
AND Location = 'SE';
于 2012-08-10T02:32:38.923 に答える
1

あなたはCTEでこれを行うことができます:

with ord (Column1, Column2) as
(
    SELECT Column1, Column2
    FROM Orders 
    WHERE Location = 'SE'
)
SELECT *
FROM ord
WHERE Quantity BETWEEN 1 AND 100

EXCEPT

SELECT *
FROM ord
WHERE Quantity BETWEEN 50 AND 75

CTEが利用できない場合は、ビューで同じことを行うことができます。

于 2012-08-10T02:45:10.573 に答える
1

EXCEPT[ 1 ]の代わりにANDNOTを使用してセット操作を処理し、さまざまなプラットフォーム間でより強力なサポートを提供できます。

言及する価値のあること、要約:

  1. 最も可能性の低い表現を最初に置きます。
  2. 最も複雑でない式を最初に置きます。
  3. より多くの検索とより少ない検索を使用します。

左から右ではなく右から左への評価のためにOracleを使用する場合は、ポイント1と2を逆にします。

于 2012-08-10T02:59:34.963 に答える
0
SELECT *
FROM   Orders
WHERE  ((Quantity BETWEEN 1 AND 49) OR (Quantity BETWEEN 76 AND 100))
AND Location = 'SE'

このクエリを試して、同じ結果を取得することを確認してください。

于 2012-08-10T02:34:02.137 に答える
0

私はそれをこのようにします:

SELECT *
FROM   Orders
WHERE  ((Quantity BETWEEN 1 AND 49)
OR (Quantity BETWEEN 76 AND 100))
AND Location = 'SE';
于 2012-08-10T02:34:16.737 に答える
-1
SELECT * 
FROM   Orders o1
WHERE  Quantity BETWEEN 1 AND 100 
AND Location = 'SE'
AND NOT EXISTS ( SELECT 1 FROM ORDERS o2 
                 WHERE QUANTITY BETWEEN 50 AND 75 
                 AND Location = 'SE' 
                 AND o1.ORDERS_ID = o2.ORDERS_ID)
于 2012-08-10T02:38:21.510 に答える