18

私の質問-

select cu.CustomerID,cu.FirstName,cu.LastName, COUNT(si.InvoiceID)as inv --1
from Customer as cu inner join SalesInvoice as si --2
on cu.CustomerID = si.CustomerID -- 3
-- put the WHERE clause here ! --4   
group by cu.CustomerID,cu.FirstName,cu.LastName -- 5
where cu.FirstName = 'mark' -- 6

正しいコードで出力-

ここに画像の説明を入力してください

エラーiget-キーワード'where'の近くの構文が正しくありません。

このエラーが発生する理由を教えてください。WHEREがGROUPBYの後にではなく、前に来る理由を知りたいです。

4

5 に答える 5

43

順序が間違っています。WHERE句は:の前にありGROUP BYます

select cu.CustomerID,cu.FirstName,cu.LastName, COUNT(si.InvoiceID)as inv 
from Customer as cu 
inner join SalesInvoice as si 
   on cu.CustomerID = si.CustomerID 
where cu.FirstName = 'mark' 
group by cu.CustomerID,cu.FirstName,cu.LastName

の後にフィルターを実行する場合は、次の句GROUP BYを使用します。HAVING

select cu.CustomerID,cu.FirstName,cu.LastName, COUNT(si.InvoiceID)as inv 
from Customer as cu 
inner join SalesInvoice as si 
   on cu.CustomerID = si.CustomerID 
group by cu.CustomerID,cu.FirstName,cu.LastName
having cu.FirstName = 'mark' 

句は通常、集計関数のHAVINGフィルタリングに使用されるため、これがGROUP BY

ここで操作の順序について学ぶために、順序を説明する記事があります。記事から、SQLでの操作の順序は次のとおりです。

まず、SQLディレクティブが実行される順序を調べるとよいと思いました。これにより、最適化の方法が変わるからです。

FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause

この順序を使用して、のWHERE前にフィルターを適用しますGROUP BY。はWHERE、レコード数を制限するために使用されます。

このように考えてください。WHEREその後を適用する場合は、グループ化するよりも多くのレコードを返すことになります。最初に適用し、レコードセットを減らしてから、グループ化を適用します。

于 2012-12-22T20:23:47.193 に答える
5

概念的には、グループ化した後ではなく、グループ化する前にフィルタリングするため、このwhere句は前にあります。group byフィルタが原因で破棄される可能性のあるアイテムに対してグループ化を実行するのではなく、グループ化されたの出力を一致するものだけに制限する必要があります。

于 2012-12-22T20:27:48.080 に答える
3

SQLでは、GROUPBYの結果をフィルタリングできます。これはHAVING句と呼ばれます。

グループ化の前に決定できるもの(つまり、FirstName ='Mark'を持つ全員)でフィルタリングする場合は、WHEREを介して実行されます。

ただし、4つ以上の請求書(つまり、COUNTを実行するまでわからないもの)を持つすべての人をフィルタリングする場合は、HAVINGを使用します。

于 2012-12-22T20:27:36.697 に答える
3

このWHERE句はGROUP BY、より意味があるため、の前に使用されます。WHERE句で指定されたフィルターは、グループ化の前に使用されます。グループ化した後、集計値でフィルタリングできることを除いHAVINGて、に似た句を作成できます。WHERE

比較:

-- Select the number of invoices per customer (for Customer 1 only)
SELECT
  si.CustomerID,
  COUNT(*) as InvoiceCount
FROM
  SalesInvoice as si   
WHERE
  si.CustomerID = 1
  -- You cannot filter by count(*) here, because grouping hasn't taken place yet.
GROUP BY 
  si.CustomerID -- (Not needed in this case, because of only 1 customer) 

に対して

-- Select all invoices of customers that have more than three invoices
SELECT
  si.CustomerID,
  COUNT(*) as InvoiceCount
FROM
  SalesInvoice as si   
GROUP BY
  si.CustomerId
HAVING
  -- You can filter by aggregates, like count, here.
  COUNT(*) > 3
于 2012-12-22T20:29:47.387 に答える
1

データベースに100,000人がいるとしましょう。そのうちの9人はマークと名付けられています。データベースが100,000個すべてに対してカウント操作を実行してから、Markという名前ではない99,991個を破棄する必要があるのはなぜですか?最初にマークを除外してから、カウントを9回だけ行う方が賢明ではないでしょうか。操作が大幅に高速化されます。

于 2012-12-22T20:55:19.277 に答える