SQL
WHEREおよびHAVINGを使用して結果をフィルタリングする
サーチ…
構文
- SELECT column_name
FROM table_name
WHERE column_name演算子の値 - SELECT column_name、aggregate_function(column_name)
FROM table_name
GROUP BY column_name
集計関数(column_name)演算子の値を保持する
WHERE句は、条件に一致する行のみを返します
Steamは店舗ページの10ドル以下のゲームを持っています。彼らのシステムの心臓部のどこかに、恐らく次のようなクエリがあります:
SELECT *
FROM Items
WHERE Price < 10
INを使用して、リストに含まれる値を持つ行を戻します。
この例では、サンプルデータベースのCar Tableを使用しています。
SELECT *
FROM Cars
WHERE TotalCost IN (100, 200, 300)
このクエリは、コスト200のCar#2と、コスト100のCar#3を返します。これは、 OR
を含む複数の句を使用することに相当します。
SELECT *
FROM Cars
WHERE TotalCost = 100 OR TotalCost = 200 OR TotalCost = 300
LIKEを使用して一致する文字列と部分文字列を検索する
LIKE演算子の完全なドキュメントを参照してください。
この例では、サンプルデータベースのEmployeesテーブルを使用しています。
SELECT *
FROM Employees
WHERE FName LIKE 'John'
このクエリは、最初の名前が「John」と正確に一致するEmployee#1を返します。
SELECT *
FROM Employees
WHERE FName like 'John%'
%
追加すると、部分文字列を検索することができます:
-
John%
- 名前が 'John'で始まり、その後に任意の文字数が続くEmployeeを返します -
%John
- 名前が 'John'で終わり、任意の文字数だけ進んだEmployeeを返します -
%John%
- 名前のどこにでも 'John'が含まれているEmployeeを返します
この場合、クエリは、名前が「John」である従業員#2と、名前が「Johnathon」である従業員#4を返します。
NULL / NOT NULL値を持つWHERE句
SELECT *
FROM Employees
WHERE ManagerId IS NULL
このステートメントは、 ManagerId
列の値がNULL
EmployeeレコードをすべてNULL
。
結果は次のようになります。
Id FName LName PhoneNumber ManagerId DepartmentId
1 James Smith 1234567890 NULL 1
SELECT *
FROM Employees
WHERE ManagerId IS NOT NULL
このステートメントは、 ManagerId
の値がNULL
でないすべての従業員レコードを返しNULL
。
結果は次のようになります。
Id FName LName PhoneNumber ManagerId DepartmentId
2 John Johnson 2468101214 1 1
3 Michael Williams 1357911131 1 2
4 Johnathon Smith 1212121212 2 1
注: WHERE節をWHERE ManagerId = NULL
またはWHERE ManagerId <> NULL
変更すると、同じ照会で結果が返されません。
集合関数でHAVINGを使用する
WHERE
句とは異なり、 HAVING
は集約関数で使用できます。
集計関数は、複数の行の値が、より重要な意味または測定値( Wikipedia )の単一の値を形成するために、特定の基準で入力としてグループ化される関数です。
一般的な集計関数には、 COUNT()
、 SUM()
、 MIN()
、 MAX()
ます。
この例では、サンプルデータベースのCar Tableを使用しています。
SELECT CustomerId, COUNT(Id) AS [Number of Cars]
FROM Cars
GROUP BY CustomerId
HAVING COUNT(Id) > 1
このクエリはNumber of Cars
するCustomerId
およびNumber of Cars
数を返します。この場合、複数の車を持つ唯一の顧客は顧客#1です。
結果は次のようになります。
顧客ID | 車の数 |
---|---|
1 | 2 |
BETWEENを使用して結果をフィルタリングする
次の例では、 Item SalesおよびCustomersサンプル・データベースを使用しています。
注:BETWEEN演算子はインクルーシブです。
NumbersでBETWEEN演算子を使う:
SELECT * From ItemSales
WHERE Quantity BETWEEN 10 AND 17
このクエリは、10以上17以下の数量を持つすべてのItemSales
レコードを返します。結果は次のようになります。
イド | セール日 | ItemId | 量 | 価格 |
---|---|---|---|---|
1 | 2013-07-01 | 100 | 10 | 34.5 |
4 | 2013-07-23 | 100 | 15 | 34.5 |
5 | 2013年7月24日 | 145 | 10 | 34.5 |
日付値にBETWEEN演算子を使用する:
SELECT * From ItemSales
WHERE SaleDate BETWEEN '2013-07-11' AND '2013-05-24'
このクエリは2013年7月11日以上2013年5月24日以下のSaleDate
を持つすべてのItemSales
レコードを返します。
イド | セール日 | ItemId | 量 | 価格 |
---|---|---|---|---|
3 | 2013-07-11 | 100 | 20 | 34.5 |
4 | 2013-07-23 | 100 | 15 | 34.5 |
5 | 2013年7月24日 | 145 | 10 | 34.5 |
日付の代わりに日時の値を比較する場合は、日時の値を日付の値に変換するか、正しい結果を得るために24時間を加算または減算する必要があります。
テキスト値でのBETWEEN演算子の使用:
SELECT Id, FName, LName FROM Customers
WHERE LName BETWEEN 'D' AND 'L';
実例: SQL fiddle
このクエリは、名前がアルファベット「D」と「L」の間に入る顧客をすべて返します。この場合、顧客#1と#3が返されます。名前が「M」で始まる顧客#2は含まれません。
イド | FName | LName |
---|---|---|
1 | ウィリアム | ジョーンズ |
3 | リチャード | デイビス |
平等
SELECT * FROM Employees
このステートメントは、 Employees
テーブルからすべての行を返します。
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate
1 James Smith 1234567890 NULL 1 1000 01-01-2002 01-01-2002 01-01-2002
2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002
3 Michael Williams 1357911131 1 2 600 12-05-2009 12-05-2009 NULL
4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
SELECT
ステートメントの最後にWHERE
を使用すると、返された行を条件に限定することができます。この場合、 =
記号を使用して完全に一致する部分は次のとおりです。
SELECT * FROM Employees WHERE DepartmentId = 1
DepartmentId
が1
行だけを返します。
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate
1 James Smith 1234567890 NULL 1 1000 01-01-2002 01-01-2002 01-01-2002
2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002
4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
ANDとOR
また、複数の演算子を組み合わせて、より複雑なWHERE
条件を作成することもできます。次の例では、 Employees
テーブルを使用しています。
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate
1 James Smith 1234567890 NULL 1 1000 01-01-2002 01-01-2002 01-01-2002
2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002
3 Michael Williams 1357911131 1 2 600 12-05-2009 12-05-2009 NULL
4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
そして
SELECT * FROM Employees WHERE DepartmentId = 1 AND ManagerId = 1
戻ります:
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate
2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002
または
SELECT * FROM Employees WHERE DepartmentId = 2 OR ManagerId = 2
戻ります:
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate
3 Michael Williams 1357911131 1 2 600 12-05-2009 12-05-2009 NULL
4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
HAVINGを使用して、グループ内の複数の条件をチェックする
注文表
顧客ID | 製品番号 | 量 | 価格 |
---|---|---|---|
1 | 2 | 5 | 100 |
1 | 3 | 2 | 200 |
1 | 4 | 1 | 500 |
2 | 1 | 4 | 50 |
3 | 5 | 6 | 700 |
ProductID 2と3の両方を注文した顧客を確認するには、HAVINGを使用できます
select customerId
from orders
where productID in (2,3)
group by customerId
having count(distinct productID) = 2
戻り値:
顧客ID |
---|
1 |
問合せでは、質問内のproductIDを持つレコードのみを選択し、HAVING句を使用して2つのproductIdsを持つグループをチェックします。
別の可能性は
select customerId
from orders
group by customerId
having sum(case when productID = 2 then 1 else 0 end) > 0
and sum(case when productID = 3 then 1 else 0 end) > 0
このクエリは、productID 2のレコードとproductID 3のレコードの少なくとも1つを持つグループのみを選択します。
どこにいるの?
内のレコードを選択しますTableName
に一致するレコード持っTableName1
。
SELECT * FROM TableName t WHERE EXISTS (
SELECT 1 FROM TableName1 t1 where t.Id = t1.Id)