次の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);
理由は何ですか?ありがとう。
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
が削除されます。
HAVING
は集計に対して動作します。 COUNT
は集約関数であるため、WHERE
句では使用できません。
こちら 集計関数に関するMSDNからの読書。
まず、句の実行順序を知っておく必要がありますFROM> WHERE> GROUP BY> HAVING> DISTINCT> SELECT> ORDER BY。以来WHERE句は前に実行されます- GROUP BY句WHEREをGROUP BY適用済みレコードに適用することで、レコードをフィルタリングできません。
「HAVINGはWHERE句と同じですが、グループ化されたレコードに適用されます」
最初にWHERE句が条件に基づいてレコードをフェッチし、次にGROUP BY句がそれに応じてレコードをグループ化し、次にHAVING句がフェッチしますグループは、条件に基づいて記録します。
WHERE句はSELECT、INSERT、およびUPDATEステートメントで使用できますが、HAVINGはSELECTステートメントでのみ使用できます。
WHEREは集計前に行をフィルタリングし(GROUP BY)、集約が実行された後はHAVINGフィルターグループを実行します。
集計関数は、HAVING句に含まれるサブクエリ内にない限りWHERE句で使用できませんが、集計関数はHAVING句で使用できます。
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を使用して必要な行だけをフィルターで除外することができました。
Whereは条件に基づいてレコードをフェッチし、レコードごとにテーブルに入り、指定した条件に基づいてレコードをフェッチするため、集計関数でwhere句を使用することはできません。そのため、where句は使用できません。 having句は、クエリを実行した後に最終的に取得するresultSetで機能します。
クエリの例:
select empName, sum(Bonus)
from employees
order by empName
having sum(Bonus) > 5000;
これにより、resultSetが一時メモリに保存され、having句が処理を実行します。したがって、ここで集計関数を簡単に使用できます。
1. WHERE句ではなくHAVING句で集計関数を使用できます。最小・最大・平均。
2. WHERE句はTuple by Tupleレコードを削除しますHAVING句はグループのコレクションからグループ全体を削除します
データのグループがある場合は主にHAVINGが使用され、行にデータがある場合はWHEREが使用されます。