SQL HAVING 句
WHERE キーワードは集計関数と共に使用できないため、SQL に HAVING 句が追加されました。
HAVING 構文
SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
HAVING condition
ORDER BY column_name(s);
デモデータベース
以下は、Northwind サンプルデータベースの “Customers” テーブルからの選択です:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
SQL HAVING の例
以下の SQL 文は、各国における顧客数をリストアップし、顧客数が5人以上の国のみを含みます:
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country
HAVING COUNT(CustomerID) > 5;
以下の SQL 文は、顧客数が多い順に各国の顧客数をリストアップします(顧客数が5人以上の国のみを含む):
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country
HAVING COUNT(CustomerID) > 5
ORDER BY COUNT(CustomerID) DESC;
デモデータベース
以下は、Northwind サンプルデータベースの “Orders” テーブルからの選択です:
OrderID | CustomerID | EmployeeID | OrderDate | ShipperID |
---|---|---|---|---|
10248 | 90 | 5 | 1996-07-04 | 3 |
10249 | 81 | 6 | 1996-07-05 | 1 |
10250 | 34 | 4 | 1996-07-08 | 2 |
そして “Employees” テーブルからの選択です:
EmployeeID | LastName | FirstName | BirthDate | Photo | Notes |
---|---|---|---|---|---|
1 | Davolio | Nancy | 1968-12-08 | EmpID1.pic | 教育はBAを含む… |
2 | Fuller | Andrew | 1952-02-19 | EmpID2.pic | AndrewはBTSを受け取った… |
3 | Leverling | Janet | 1963-08-30 | EmpID3.pic | JanetはBSの学位を持っています… |
さらに HAVING の例
以下の SQL 文は、10件以上の注文を登録している従業員をリストアップします:
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders
FROM (Orders
INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID)
GROUP BY LastName
HAVING COUNT(Orders.OrderID) > 10;
以下の SQL 文は、”Davolio” または “Fuller” の従業員が25件以上の注文を登録しているかをリストアップします:
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders
FROM Orders
INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID
WHERE LastName = 'Davolio' OR LastName = 'Fuller'
GROUP BY LastName
HAVING COUNT(Orders.OrderID) > 25;
SQL GROUP BY 文
GROUP BY 文は、”国ごとの顧客数を見つける” のように、同じ値を持つ行をまとめて集計行にします。
GROUP BY 文は、一つまたは複数の列で結果セットを集計関数(COUNT()、MAX()、MIN()、SUM()、AVG())でグループ化する際によく使用されます。
GROUP BY 構文
SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
ORDER BY column_name(s);
デモデータベース
以下は、Northwind サンプルデータベースの “Customers” テーブルからの選択です:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
5 | Berglunds snabbköp | Christina Berglund | Berguvsvägen 8 | Luleå | S-958 22 | Sweden |
SQL GROUP BY の例
以下の SQL 文は、各国の顧客数をリストアップします:
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country;
以下の SQL 文は、顧客数が多い順に各国の顧客数をリストアップします:
SELECT COUNT(CustomerID), Country
FROM Customers
GROUP BY Country
ORDER BY COUNT(CustomerID) DESC;
デモデータベース
以下は、Northwind サンプルデータベースの “Orders” テーブルからの選択です:
OrderID | CustomerID | EmployeeID | OrderDate | ShipperID |
---|---|---|---|---|
10248 | 90 | 5 | 1996-07-04 | 3 |
10249 | 81 | 6 | 1996-07-05 | 1 |
10250 | 34 | 4 | 1996-07-08 | 2 |
そして “Shippers” テーブルからの選択です:
ShipperID | ShipperName |
---|---|
1 | Speedy Express |
2 | United Package |
3 | Federal Shipping |
JOIN と GROUP BY の例
以下の SQL 文は、各配送業者が送信した注文の数をリストアップします:
SELECT Shippers.ShipperName, COUNT(Orders.OrderID) AS NumberOfOrders FROM Orders
LEFT JOIN Shippers ON Orders.ShipperID = Shippers.ShipperID
GROUP BY ShipperName;
SQL UNION 演算子
UNION 演算子は、2つ以上の SELECT 文の結果セットを結合するために使用されます。
UNION 構文
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
UNION ALL 構文
UNION 演算子はデフォルトで重複値を選択しません。重複値を許可するには、UNION ALL を使用します:
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
注:結果セットの列名は通常、最初の SELECT 文の列名と同じです。
デモデータベース
このチュートリアルでは、よく知られた Northwind サンプルデータベースを使用します。
“Customers” テーブルからの選択です:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
“Suppliers” テーブルからの選択です:
SupplierID | SupplierName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Exotic Liquid | Charlotte Cooper | 49 Gilbert St. | London | EC1 4SD | UK |
2 | New Orleans Cajun Delights | Shelley Burke | P.O. Box 78934 | New Orleans | 70117 | USA |
3 | Grandma Kelly’s Homestead | Regina Murphy | 707 Oxford Rd. | Ann Arbor | 48104 | USA |
SQL UNION の例
以下の SQL 文は、”Customers” テーブルと “Suppliers” テーブルからの都市名(重複を排除した値のみ)を返します:
SELECT City FROM Customers
UNION
SELECT City FROM Suppliers
ORDER BY City;
注:顧客またはサプライヤーが同じ都市にある場合、UNION は重複値のみをリストアップします。重複値も選択するには UNION ALL を使用してください!
SQL UNION ALL の例
以下の SQL 文は、”Customers” テーブルと “Suppliers” テーブルからの都市名(重複値も含む)を返します:
SELECT City FROM Customers
UNION ALL
SELECT City FROM Suppliers
ORDER BY City;
SQL UNION と WHERE
以下の SQL 文は、”Customers” テーブルと “Suppliers” テーブルからのドイツの都市名(重複を排除した値のみ)を返します:
SELECT City, Country FROM Customers
WHERE Country='Germany'
UNION
SELECT City, Country FROM Suppliers
WHERE Country='Germany'
ORDER BY City;
SQL UNION ALL と WHERE
以下の SQL 文は、”Customers” テーブルと “Suppliers” テーブルからのドイツの都市名(重複値も含む)を返します:
SELECT City, Country FROM Customers
WHERE Country='Germany'
UNION ALL
SELECT City, Country FROM Suppliers
WHERE Country='Germany'
ORDER BY City;
別の UNION の例
以下の SQL 文は、すべての顧客とサプライヤーをリストアップします:
SELECT 'Customer' AS Type, ContactName, City, Country
FROM Customers
UNION
SELECT 'Supplier', ContactName, City, Country
FROM Suppliers;
上記の “AS Type” に注目してください – これはエイリアスです。SQL エイリアスは、テーブルや列に一時的な名前を付けるために使用されます。エイリアスはクエリの実行中だけ存在します。ここでは一時的な列 “Type” を作成しました。この列は、連絡先が “Customer” または “Supplier” であるかを示します。
SQL Self Join
自己結合(Self Join)は、通常の結合ですが、テーブルが自分自身と結合されます。
Self Join の構文
SELECT column_name(s)
FROM table1 T1, table1 T2
WHERE condition;
T1 と T2 は同じテーブルの異なるテーブルエイリアスです。
デモデータベース
このチュートリアルでは、よく知られた Northwind サンプルデータベースを使用します。
“Customers” テーブルからの選択です:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
SQL Self Join の例
以下の SQL 文は、同じ都市から来た顧客をマッチングします:
SELECT A.CustomerName AS CustomerName1, B.CustomerName AS CustomerName2, A.City
FROM Customers A, Customers B
WHERE A.CustomerID <> B.CustomerID
AND A.City = B.City
ORDER BY A.City;
SQL FULL OUTER JOIN キーワード
FULL OUTER JOIN キーワードは、左側のテーブル(table1)または右側のテーブル(table2)のレコードが一致する場合にすべてのレコードを返します。
Tip: FULL OUTER JOIN と FULL JOIN は同じです。
FULL OUTER JOIN の構文
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name = table2.column_name
WHERE condition;
注意: FULL OUTER JOIN は非常に大きな結果セットを返す可能性があります!
デモデータベース
このチュートリアルでは、よく知られた Northwind サンプルデータベースを使用します。
“Customers” テーブルからの選択です:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
そして、”Orders” テーブルからの選択です:
OrderID | CustomerID | EmployeeID | OrderDate | ShipperID |
---|---|---|---|---|
10308 | 2 | 7 | 1996-09-18 | 3 |
10309 | 37 | 3 | 1996-09-19 | 1 |
10310 | 77 | 8 | 1996-09-20 | 2 |
SQL FULL OUTER JOIN の例
以下の SQL 文は、すべての顧客とすべての注文を選択します:
SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
FULL OUTER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CustomerName;
注意: FULL OUTER JOIN キーワードは、両方のテーブルから一致するレコードをすべて返します。したがって、「Customers」には「Orders」に一致しない行がある場合、または「Orders」には「Customers」に一致しない行がある場合、それらの行もリストされます。
SQL RIGHT JOIN キーワード
RIGHT JOIN キーワードは、右側のテーブル(table2)からすべてのレコードと、左側のテーブル(table1)からの一致するレコードを返します。左側のテーブルに一致するレコードがない場合は、結果には0件のレコードが含まれます。
RIGHT JOIN の構文
SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name;
注意: 一部のデータベースでは RIGHT JOIN は RIGHT OUTER JOIN と呼ばれます。
デモデータベース
このチュートリアルでは、よく知られた Northwind サンプルデータベースを使用します。
“Orders” テーブルからの選択です:
OrderID | CustomerID | EmployeeID | OrderDate | ShipperID |
---|---|---|---|---|
10308 | 2 | 7 | 1996-09-18 | 3 |
10309 | 37 | 3 | 1996-09-19 | 1 |
10310 | 77 | 8 | 1996-09-20 | 2 |
そして、”Employees” テーブルからの選択です:
EmployeeID | LastName | FirstName | BirthDate | Photo |
---|---|---|---|---|
1 | Davolio | Nancy | 12/8/1968 | EmpID1.pic |
2 | Fuller | Andrew | 2/19/1952 | EmpID2.pic |
3 | Leverling | Janet | 8/30/1963 | EmpID3.pic |
以下の SQL 文は、すべての従業員と、彼らが配置した可能性のある注文を返します:
SELECT Orders.OrderID, Employees.LastName, Employees.FirstName
FROM Orders
RIGHT JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID
ORDER BY Orders.OrderID;
注意: RIGHT JOIN キーワードは、右側のテーブル(Employees)からすべてのレコードを返します。左側のテーブル(Orders)に一致するレコードがなくても、そのレコードが含まれます。
SQL LEFT JOIN キーワード
LEFT JOIN キーワードは、左側のテーブル(table1)からすべてのレコードと、右側のテーブル(table2)からの一致するレコードを返します。右側のテーブルに一致するレコードがない場合は、結果には0件のレコードが含まれます。
LEFT JOIN の構文
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name;
注意: 一部のデータベースでは LEFT JOIN は LEFT OUTER JOIN と呼ばれます。
デモデータベース
このチュートリアルでは、よく知られた Northwind サンプルデータベースを使用します。
“Customers” テーブルからの選択です:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
そして、”Orders” テーブルからの選択です:
OrderID | CustomerID | EmployeeID | OrderDate | ShipperID |
---|---|---|---|---|
10308 | 2 | 7 | 1996-09-18 | 3 |
10309 | 37 | 3 | 1996-09-19 | 1 |
10310 | 77 | 8 | 1996-09-20 | 2 |
以下の SQL 文は、すべての顧客とその持つ可能性のある注文を選択します:
SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CustomerName;
注意: LEFT JOIN キーワードは、左側のテーブル(Customers)からすべてのレコードを返します。右側のテーブル(Orders)に一致するレコードがなくても、そのレコードが含まれます。
INNER JOIN
INNER JOIN キーワードは、両方のテーブルで一致する値を持つレコードを選択します。
Products テーブルの一部を見てみましょう:
ProductID | ProductName | CategoryID | Price |
---|---|---|---|
1 | Chais | 1 | 18 |
2 | Chang | 1 | 19 |
3 | Aniseed Syrup | 2 | 10 |
そして、Categories テーブルの一部を見てみましょう:
CategoryID | CategoryName | Description |
---|---|---|
1 | Beverages | Soft drinks, coffees, teas, beers, and ales |
2 | Condiments | Sweet and savory sauces, relishes, spreads, and seasonings |
3 | Confections | Desserts, candies, and sweet breads |
Products テーブルと Categories テーブルを、両方のテーブルの CategoryID フィールドを使用して結合します:
SELECT ProductID, ProductName, CategoryName
FROM Products
INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID;
INNER JOIN キーワードは、両方のテーブルで一致するレコードのみを返します。つまり、CategoryID がない製品、または Categories テーブルに存在しない CategoryID を持つ製品は結果に含まれません。
Syntax
SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name;
列の命名
SQL 文で列を指定する際には、テーブル名を含めるのが良い習慣です。
SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Products
INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID;
上記の例では、両方のテーブルに指定された列名が存在しないため、テーブル名を指定しなくても動作します。ただし、SELECT 文に CategoryID を含めようとすると、テーブル名を指定しないとエラーが発生します(CategoryID が両方のテーブルに存在するため)。
JOIN または INNER JOIN
JOIN と INNER JOIN は同じ結果を返します。
SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Products
JOIN Categories ON Products.CategoryID = Categories.CategoryID;
3 つのテーブルを JOIN する
以下の SQL 文は、顧客と配送業者の情報を持つすべての注文を選択します:
以下が Shippers テーブルです:
ShipperID | ShipperName | Phone |
---|---|---|
1 | Speedy Express | (503) 555-9831 |
2 | United Package | (503) 555-3199 |
3 | Federal Shipping | (503) 555-9931 |
SELECT Orders.OrderID, Customers.CustomerName, Shippers.ShipperName
FROM ((Orders
INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID)
INNER JOIN Shippers ON Orders.ShipperID = Shippers.ShipperID);
SQL ジョイン
JOIN 句は、関連する列を基に、2 つ以上のテーブルから行を結合するために使用されます。
“Orders” テーブルから選択された一部を見てみましょう:
OrderID | CustomerID | OrderDate |
---|---|---|
10308 | 2 | 1996-09-18 |
10309 | 37 | 1996-09-19 |
10310 | 77 | 1996-09-20 |
次に、”Customers” テーブルから選択された一部を見てみましょう:
CustomerID | CustomerName | ContactName | Country |
---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mexico |
“Orders” テーブルの “CustomerID” 列が “Customers” テーブルの “CustomerID” 列を参照していることに注意してください。上記の 2 つのテーブルの関係性は “CustomerID” 列です。
次に、以下の SQL 文(INNER JOIN を含む)を作成できます。この SQL 文は、両方のテーブルで一致する値を持つレコードを選択します:
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;
この SQL 文は次のような結果を生成します:
OrderID | CustomerName | OrderDate |
---|---|---|
10308 | Ana Trujillo Emparedados y helados | 9/18/1996 |
10365 | Antonio Moreno Taquería | 11/27/1996 |
10383 | Around the Horn | 12/16/1996 |
10355 | Around the Horn | 11/15/1996 |
10278 | Berglunds snabbköp | 8/12/1996 |
以下は SQL における異なる種類の JOIN の説明です:
SQL エイリアス
SQL エイリアスはテーブルまたはテーブル内の列に一時的な名前を付けるために使用されます。
エイリアスはしばしば列名をより読みやすくするために使用されます。
エイリアスはそのクエリの実行中のみ存在します。
エイリアスは AS キーワードで作成されます。
Customers テーブルから CustomerID 列を ID として選択します:
SELECT CustomerID AS ID
FROM Customers;
AS キーワードは実際にはほとんどのデータベース言語で省略することができ、同じ結果を得ることができます:
SELECT CustomerID ID
FROM Customers;
列にエイリアスを使用する場合:
SELECT column_name AS alias_name
FROM table_name;
テーブルにエイリアスを使用する場合:
SELECT column_name(s)
FROM table_name AS alias_name;
以下は、例に使用される Customers および Orders テーブルからの選択です:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Germany |
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
OrderID | CustomerID | EmployeeID | OrderDate | ShipperID |
---|---|---|---|---|
10248 | 90 | 5 | 7/4/1996 | 3 |
10249 | 81 | 6 | 7/5/1996 | 1 |
10250 | 34 | 4 | 7/8/1996 | 2 |
以下の SQL 文は、CustomerID 列と CustomerName 列のためにそれぞれ ID と Customer のエイリアスを作成します:
SELECT CustomerID AS ID, CustomerName AS Customer
FROM Customers;
エイリアスにスペースを含めたい場合、「My Great Products」のように、エイリアスを角かっこまたは二重引用符で囲みます。
SELECT ProductName AS [My Great Products]
FROM Products;
SELECT ProductName AS "My Great Products"
FROM Products;
注:一部のデータベースシステムは両方の方法を許可していますが、一部はどちらか一方のみを許可しています。
以下の SQL 文は、Address、PostalCode、City、Country の 4 つの列を結合して Address というエイリアスを作成します:
SELECT CustomerName, Address + ', ' + PostalCode + ' ' + City + ', ' + Country AS Address
FROM Customers;
注:MySQL で上記の SQL 文を動作させるには、次のようにします:
SELECT CustomerName, CONCAT(Address,', ',PostalCode,', ',City,', ',Country) AS Address
FROM Customers;
注:Oracle で上記の SQL 文を動作させるには、次のようにします:
SELECT CustomerName, (Address || ', ' || PostalCode || ' ' || City || ', ' || Country) AS Address
FROM Customers;
テーブルのえいを使用する場合も同様のルールが適用されます。
例:
SELECT * FROM Customers AS Persons;
テーブルにエイリアスを使用するのは無駄に思えるかもしれませんが、複数のテーブルをクエリで使用する場合、SQL 文を短くすることができます。
以下の SQL 文は、Customers テーブルと Orders テーブルから、テーブルのエイリアスをそれぞれ “c” および “o” として使用しています(SQL を短くするためにエイリアスを使用しています):
SELECT o.OrderID, o.OrderDate, c.CustomerName
FROM Customers AS c, Orders AS o
WHERE c.CustomerName='Around the Horn' AND c.CustomerID=o.CustomerID;
以下の SQL 文は、エイリアスを使用せずに同じです:
SELECT Orders.OrderID, Orders.OrderDate, Customers.CustomerName
FROM Customers, Orders
WHERE Customers.CustomerName='Around the Horn' AND Customers.CustomerID=Orders.CustomerID;
エイリアスは以下のような場面で便利です: