web-dev-qa-db-ja.com

SQL-VSを持っているところ

次の2つのテーブルがあります。

1. Lecturers (LectID, Fname, Lname, degree).
2. Lecturers_Specialization (LectID, Expertise).

最も専門性の高い講師を探したいです。私がこれを試しても、うまくいきません:

SELECT
  L.LectID, 
  Fname, 
  Lname 
FROM Lecturers L, 
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
AND COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID);

しかし、これを試してみるとうまくいきます:

SELECT
  L.LectID,
  Fname,
  Lname 
FROM Lecturers L,
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
GROUP BY L.LectID,
         Fname,
         Lname 
HAVING COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID); 

理由は何ですか?ありがとう。

170
Adam Sh

WHERE句は、個々の行;の条件を導入します。 HAVING句は、集約の条件を導入します。つまり、カウント、平均、最小、最大、または合計などの単一の結果が複数行から生成された選択結果。クエリは2種類目の条件(つまり、集約の条件)を必要とするため、HAVINGは正しく機能します。

経験則として、GROUP BYの前にWHEREを使用し、GROUP BYの後にHAVINGを使用します。これはかなり原始的なルールですが、90%以上のケースで役立ちます。

その間、ANSIバージョンの結合を使用してクエリを書き直したい場合があります。

SELECT  L.LectID, Fname, Lname
FROM Lecturers L
JOIN Lecturers_Specialization S ON L.LectID=S.LectID
GROUP BY L.LectID, Fname, Lname
HAVING COUNT(S.Expertise)>=ALL
(SELECT COUNT(Expertise) FROM Lecturers_Specialization GROUP BY LectID)

これにより、シータ結合条件として使用されていたWHEREが削除されます。

309
dasblinkenlight

HAVINGは集計に対して動作します。 COUNTは集約関数であるため、WHERE句では使用できません。

こちら 集計関数に関するMSDNからの読書。

35
Daniel Mann

まず、句の実行順序を知っておく必要がありますFROM> WHERE> GROUP BY> HAVING> DISTINCT> SELECT> ORDER BY。以来WHERE句は前に実行されます- GROUP BYWHEREGROUP BY適用済みレコードに適用することで、レコードをフィルタリングできません。

「HAVINGはWHERE句と同じですが、グループ化されたレコードに適用されます」

最初にWHERE句が条件に基づいてレコードをフェッチし、次にGROUP BY句がそれに応じてレコードをグループ化し、次にHAVING句がフェッチしますグループは、条件に基づいて記録します。

20
Pardhu
  1. WHERE句はSELECT、INSERT、およびUPDATEステートメントで使用できますが、HAVINGはSELECTステートメントでのみ使用できます。

  2. WHEREは集計前に行をフィルタリングし(GROUP BY)、集約が実行された後はHAVINGフィルターグループを実行します。

  3. 集計関数は、HAVING句に含まれるサブクエリ内にない限りWHERE句で使用できませんが、集計関数はHAVING句で使用できます。

ソース

13

1つのクエリで両方の例が表示されませんでした。したがって、この例が役立ちます。

  /**
INTERNATIONAL_ORDERS - table of orders by company by location by day
companyId, country, city, total, date
**/

SELECT country, city, sum(total) totalCityOrders 
FROM INTERNATIONAL_ORDERS with (nolock)
WHERE companyId = 884501253109
GROUP BY country, city
HAVING country = 'MX'
ORDER BY sum(total) DESC

これは、まずcompanyIdでテーブルをフィルターし、次に(国と都市で)グループ化し、さらにメキシコの都市の集計のみにフィルターします。 companyIdは集約には必要ありませんでしたが、GROUP BYを使用する前に、WHEREを使用して必要な行だけをフィルターで除外することができました。

9
Nhan

Whereは条件に基づいてレコードをフェッチし、レコードごとにテーブルに入り、指定した条件に基づいてレコードをフェッチするため、集計関数でwhere句を使用することはできません。そのため、where句は使用できません。 having句は、クエリを実行した後に最終的に取得するresultSetで機能します。

クエリの例:

select empName, sum(Bonus) 
from employees 
order by empName 
having sum(Bonus) > 5000;

これにより、resultSetが一時メモリに保存され、having句が処理を実行します。したがって、ここで集計関数を簡単に使用できます。

8
Akash5288

1. WHERE句ではなくHAVING句で集計関数を使用できます。最小・最大・平均。

2. WHERE句はTuple by Tupleレコードを削除しますHAVING句はグループのコレクションからグループ全体を削除します

データのグループがある場合は主にHAVINGが使用され、行にデータがある場合はWHEREが使用されます。

4
Mihir Trivedi