2016-09-16 15 views
0

私はSQLに新しいので、私はクエリでWHERE句とHAVING句の両方を使用すると、HAVING句の条件の順序が重要になるのではないかと思います。たとえば、次のクエリ(ブックから取り出す)では、まったく同じですか? WHERE句ですでにフィルタリングされているGROUPデータにHAVINGを適用すると、SUM()関数はフィルタリングされたデータにのみ適用されます。ただし、2番目の問合せでは、WHERE句が事前に適用されておらず、HAVING句の最後にInvoiceDate BETWEEN '2016-01-01' AND '2016-01-31'という条件が適用されるため、SUM()は最初のクエリとは異なるすべてのデータから計算します。私はそれを正しく理解していますか?Having句の条件の順序はSQLで重要ですか?

-- First Query 
SELECT 
    InvoiceDate, 
    COUNT(*) AS InvoiceQty, 
    SUM(InvoiceTotal) AS InvoiceSum 
FROM 
    Invoices 
WHERE 
    InvoiceDate BETWEEN '2016-01-01' AND '2016-01-31' 
GROUP BY 
    InvoiceDate 
HAVING 
    COUNT(*) > 1 
     AND SUM(InvoiceTotal) > 100 
ORDER BY 
    InvoiceDate DESC; 

-- Second Query 
SELECT 
    InvoiceDate, 
    COUNT(*) AS InvoiceQty, 
    SUM(InvoiceTotal) AS InvoiceSum 
FROM 
    Invoices 
GROUP BY 
    InvoiceDate 
HAVING 
    COUNT(*) > 1 
     AND SUM(InvoiceTotal) > 100 
     AND InvoiceDate BETWEEN '2016-01-01' AND '2016-01-31' 
ORDER BY 
    InvoiceDate DESC; 

答えて

1

HAVING句の順序は関係ありません。とにかく仕事のほとんどはGROUP BYによって行われています。節の1つが(例えば、ユーザ定義関数の使用のために)チェックするほうがずっと高価な場合には、違いが生じる可能性があります。ただし、クエリにはこのような条件はありません。

一方、HAVINGWHEREの条件の違いは重要です。そして、あなたのように2番目のクエリを書き直すことができます。前にフィルタリング

SELECT InvoiceDate, COUNT(*) AS InvoiceQty, 
     SUM(InvoiceTotal) AS InvoiceSum 
FROM Invoices 
WHERE InvoiceDate BETWEEN '2016-01-01' AND '2016-01-31' 
GROUP BY InvoiceDate 
HAVING COUNT(*) > 1 AND SUM(InvoiceTotal) > 100 
ORDER BY InvoiceDate DESC; 

それが凝集を処理するために必要なデータの量が減少するためGROUP BYは、通常、より効率的です。

1

次の手順は、SQL Serverデータベース内のSELECTステートメントの論理的な処理順序またはバインド順序を示しています。この順序は、1つのステップで定義されたオブジェクトが後続のステップで句に使用可能になる時期を決定します。

  1. ON
  2. FROM SELECT
  3. WHERE
  4. GROUP CUBEまたは
  5. HAVING ROLLUP
  6. WITH
  7. BY JOIN
  8. DISTINCT
  9. TOP

BYORDER今あなたが順序を知っているので、あなたは処理が可能になる方法を見つけることができます。詳細は、this linkを参照してください。

0

あなたは正しく仮定しています。 2つのクエリの結果は同じですが、第1のクエリは通常はより曖昧です。なぜなら、不要なデータを破棄する前にすべての計算を行うのではなく、すぐにそのデータを破棄するからです。

データベースシステムに適切なクエリオプティマイザがある場合、2番目のクエリのHAVING句の一部をWHEREに移動して内部的にクエリを書き換えることができるので、クエリ#いずれの場合も1である。しかし、あなたはそれに頼るべきではありません。可能な限りクエリを記述します。つまり、クエリ#1を使用します。

関連する問題