データの取得
以下のトピックでは、データを取得するための SELECT ステートメントの使用について説明します。
データ取得の概要
データベースにデータを入力したら、SELECT ステートメントでそのデータを取得し、表示することができます。Zen は、要求するデータを結果テーブルで返します。SQL ステートメントでは、以下のことが行えます。
• テンポラリ ビューまたはパーマネント(ストアド)ビューを作成する。
• データベース内の 1 つまたは複数のテーブルから取り出す列を列挙する、選択リストを指定する。
• 行をソートする方法を指定する。
• 行をサブセットにグループ化する場合の基準を指定する。
• テーブルにテンポラリ名(エイリアス)を割り当てる。
• 1 つまたは複数のテーブルからデータを取得し、1 つの結果テーブルにデータを表示する(結合)。
• SELECT ステートメントでサブクエリを指定する。
• Zen が選択する行を制限するために制限句を指定する。
ビュー
ビューは、データベース内のデータを調べるためのメカニズムです。複数のテーブルのデータを結合したり、1 つのテーブルの特定の列だけを含めたりすることができます。ビューはテーブルに似ていますが、データベースのテーブルの列に基づいて選択した一連の列または計算結果から構成されています。したがって、ビューには、複数のテーブル内の列からのデータ、または実際にテーブル内にまったくないデータ、たとえば、SELECT COUNT(*)FROM Person などが含まれている場合があります。
ビューの機能
以下に、ビューのいくつかの機能を示します。
• ビューの列は、可変長の列が最後の列でなければならないということ以外、任意の順序で配列することができます。可変長の列は 1 つしか指定できません。
• 制限句を使用して、Zen がビューに返す行のセットを指定できます。制限句は、データをビューに取り込む必要のある条件を指定します。詳細については、
制限句を参照してください。
• データベースにアクセスするユーザーとアプリケーションごとに、ビューの設計とカスタマイズが行えます。これらのビューの定義は、後で呼び出すためにデータ辞書に格納できます。
• ビューが読み取り専用のビューでない限り、データを取得、更新、または削除する際に、テーブル リストにストアド ビュー名をいくつでも含めることができます。読み取り専用のビューでは、データの取得しか行えません。
• ストアド ビューでは、ビューの計算列と定数に見出しを付け、ビューからデータを取得するときにこれらの見出しの名前を列名のリストで使用しなければなりません。
テンポラリ ビューとストアド ビュー
SELECT ステートメントを使用して、テンポラリ ビューまたはストアド ビューを作成できます。テンポラリ ビューは 1 回だけ使用して、その後で解放するものです。Zen はストアド ビューの定義をデータ辞書(X$Proc)に保管するので、後でそのビューを呼び出すことができます。CREATE VIEW ステートメントを使用すると、ストアド ビューの作成と名前付けが行えます。
各ビューはデータベース内で一意であり、また 20 文字を超えることはできません。ビューに名前を付ける規則の詳細については、
データの挿入と削除を参照してください。
Zen は、データベース要素名を定義する場合に大文字と小文字を区別します。PhoNE という名前のストアド ビューを作成すると、Zen はビュー名を PhoNE として辞書に格納します。ビュー名の定義後、Zen は大文字小文字を区別しません。ストアド ビュー PhoNE を定義した後、そのビューを phone で参照することができます。
ストアド ビューを使用すると、以下の機能が実現します。
• 頻繁に実行するクエリを格納し、後で使用するために名前を付けることができます。以下の例では、Department テーブルに基づいて Phones というストアド ビューを作成します。
CREATE VIEW Phones (PName, PPhone)
AS SELECT Name, Phone_Number
FROM Department#
• データの取得、更新および削除を行う場合、テーブル リストでストアド ビューの名前を指定できます。ストアド ビューはデータベース内のテーブルであるかのように動作しますが、実際には使用する都度、Zen エンジンによって内部で再構築されます。以下の例では、ストアド ビュー Phones を参照することによって、Department テーブル内の History Department の電話番号を更新します。
UPDATE Phones
SET PPhone = '5125552426'
WHERE PName = 'History'#
• 見出しを指定できます。見出しでは、辞書の列に対して定義した名前とは異なる列名を指定します。以下の例では、ストアド ビュー Phones に見出し Department と Telephone を指定します。
CREATE VIEW Dept_Phones (Department, Telephone)
AS SELECT Name, Phone_Number
FROM Department#
以下の例に示すように、ビューの以降のクエリ内で見出しを使用できます。
SELECT Telephone
FROM Dept_Phones#
選択リストに単純な列名が含まれている場合に、見出しを指定しないと、Zen はその列名を列の見出しとして使用します。
ビューに含める定数と計算列に名前を付けるには、見出しを使用する必要があります。以下の例では、見出し Student と Total を作成します。
CREATE VIEW Accounts (Student, Total)
AS SELECT Student_ID, SUM (Amount_Paid)
FROM Billing
GROUP BY Student_ID#
重複する列名を持つ複数のテーブルから SELECT * を指定する場合にも、見出しを使用しなければなりません。
• データベースにアクセスするユーザーまたはアプリケーションごとに、カスタマイズされたビューを作成できます。これらのビューの定義は、後で呼び出すためにデータ辞書に格納できます。
ビューの読み取り専用テーブル
読み取り専用のテーブルを含んでいるビューの行を挿入、更新、または削除することはできません。(ここでいう「更新」は、挿入、更新、および削除を指します。テーブルが読み取り専用ならば、テーブルを更新できません。)一部のテーブルは、読み取り専用と指定されたビュー内にあるかどうかに関係なく、読み取り専用です。テーブルは、次のいずれかの基準を満たす場合、読み取り専用になります。
• データベースのセキュリティが有効になっており、現在のユーザーまたはユーザー グループには、データベースまたはテーブルに対して SELECT 権しか定義されていない。
• データ ファイルには、物理ファイル レベルで読み取り専用のフラグが付けられている(たとえば、DOS または Windows では ATTRIB コマンド、Linux または Raspbian では chmod コマンドを使用してフラグを付けられます)。
• ビューを作成する SELECT 句を実行し、その句に次のいずれかの項目が含まれている。
• 選択リスト内の集計関数
• GROUP BY 句または HAVING 句
• UNION
• DISTINCT キーワード
• ビューを作成する SELECT ステートメントを実行し、テーブルに次のいずれかの特性が含まれている。
• テーブルは、SELECT ステートメントの FROM 句にあるマージ不能なビューに表示される。
• テーブルはシステム テーブルである。システム テーブルは、ビューのオープン モードが何であろうと、ビューでは常に読み取り専用として開かれます。
• テーブルの列が選択リストの計算列またはスカラー関数に現れる。
• テーブルは、最も外側のクエリと相関関係を持たないサブクエリの FROM 句に現れる。サブクエリは、最も外側のクエリと直接または間接に相関関係を持たせることができます。サブクエリは、テーブルの列への参照が含まれており、その特定の発生が最も外側の FROM 句中にある場合、最も外側のクエリと直接相関関係を持ちます。サブクエリは、あるサブクエリと相関関係があって、そのサブクエリが最も外側のクエリと直接または間接に相関関係がある場合に、最も外側のクエリと間接的に相関関係があります。
• オープン モードがリードオンリーである。
• FOR UPDATE を指定せずに、次のいずれかのキーワードを指定して位置付け UPDATE ステートメントを実行する。
ORDER BY
SCROLL
マージ可能なビュー
ビューは、ベース テーブルと列だけを使用して SELECT ステートメントを書き換えることができる場合にマージ可能です。
たとえば、何人の学生が 1 クラスにいるかを知りたい場合、それを計算するビューを定義できます。以下のようにビュー NumberPerClass を定義します。
CREATE VIEW NumberPerClass (Class_Name, Number_of_Students)
AS SELECT Name, COUNT(Last_Name)
FROM Person, Class, Enrolls
WHERE Person.ID = Enrolls.Student_ID
AND Class.ID = Enrolls.Class_ID
GROUP BY Name#
以下のようにビュー NumberPerClass を定義します。
SELECT *
FROM NumberPerClass#
この場合、ビュー NumberPerClass がマージ可能なのは、以下のように SELECT ステートメントを書き換えることができるからです。
SELECT Name, COUNT(Last_Name)
FROM Person, Class, Enrolls
WHERE Person.ID = Enrolls.Student_ID
AND Class.ID = Enrolls.Class_ID
GROUP BY NAME#
以下のように SELECT ステートメントを書いた場合、ビュー NumberPerClass はマージ不能です。
SELECT COUNT(Name)
FROM NumberPerClass
WHERE Number_of_Students > 50#
このステートメントは、ビュー NumberPerClass に対して無効です。ベース テーブルとベース 列だけでは、このビューを書き換えることができません。
ビューに以下の特性が含まれていない場合、ビューはマージ可能です。
• ビューはマージ不能なビューを参照する。
• ビューは選択リストに集計関数を持つか、または DISTINCT キーワードを持っており、かつ、選択リストに集計を持つ SELECT ステートメントの FROM 句に現れる。
• ビューは DISTINCT キーワードを持ち、SELECT ステートメントの FROM 句に現れる。そのステートメントは、FROM 句に複数の項目を持ち、選択リストに集計を持たず、かつ DISTINCT キーワードを持たない。
• ビューは選択リストに集計を持ち、SELECT ステートメントの FROM 句に現れる。そのステートメントは、FROM 句に複数の項目を持つか、または WHERE 句の制限がある。
選択リスト
SELECT ステートメントを使用してデータを取得する場合は、結果テーブルに組み込む列のリスト、つまり、選択リストを指定します。テーブル内のすべての列を取得する場合、列のリストの代わりにアスタリスク(*)を使用できます。
メモ: リストの代わりに * を使用することは避けてください。* を使用すると、テーブル内の列の数または列のサイズが変化した場合にアプリケーションに潜在的な問題が生ずるおそれがあります。また、アプリケーションは一般に不必要なデータを返します。
以下の例では、Class テーブルから 3 つの列を選択します。
SELECT Name, Section, Max_Size
FROM Class;
以下の例では、Class テーブルからすべての列を選択します。
SELECT * FROM Class;
データを取得する場合、Zen はクエリで名前を指定した方法に基づいて列名を表示します。
• 列名を明示的に指定すると、Zen は入力されたとおりに列名を返します。以下の例では、列名をすべて小文字で指定します。
SELECT name, section, max_size FROM Class#
Zen は、以下のように列名を返します。
"Name", "Section", "Max_Size"
これらの列名は、返されたデータの見出しです。データ自体ではありません。
以下の例では、テーブル Department と Faculty のエイリアスを定義します。
SELECT d.Name, f.ID FROM Department d, Faculty f;
Zen は、以下のように列名を返します。
"Name", "ID"
• * を使用して列名を指定する場合、以下の例に示すように列名はすべて大文字で表示されます。
SELECT * FROM Department;
Zen は、以下のように列名を返します。
"Name", "Phone_Number", "Building_Name", "Room_Number", "Head_Of_Dept"
以下の例では、テーブル Department と Faculty のエイリアスを定義します。
SELECT * FROM Department d, Faculty f;
Zen は、以下のように列名を返します。
"Name"
"Phone_Number"
"Building_Name"
"Room_Number"
"Head_Of_Dept"
"ID"
"Dept_Name"
"Designation"
"Salary"
"Building_Name"
"Room_Number"
"Rsch_Grant_Amount"
ソートされた行とグループ化された行
結果テーブルにどのようなデータを組み入れるかを決定すると、データの順序を指定できます。ORDER BY 句を使用してデータをソートしたり、GROUP BY 句を使用してある列単位で行をグループ化することができます。データをグループ化すると、集計関数を使用してグループ単位でデータを要約することもできます。集計関数の詳細については、
集計関数を参照してください。
以下の例では、サンプル データベースの Person テーブルにラスト ネームですべての行の順序を指定します。
SELECT *
FROM Person
ORDER BY Last_Name#
以下の例では、Room テーブル内の Building Name 列で結果をグループ化します。この例では、2 つの集計関数 COUNT と SUM も使用します。
SELECT Building_Name, COUNT(Number), SUM(Capacity)
FROM Room
GROUP BY Building_Name;
結合
結合は、列を複数のテーブルから 1 つのビューに結合するステートメントから発生します。データが読み取り専用でなければ、このビューからデータの取得、挿入、更新または削除を行えます。
メモ: ここでは、主に、SELECT ステートメントによるテーブルの結合について説明します。ただし、1 つのステートメントを複数のテーブルに適用することによって、INSERT、UPDATE、および DELETE ステートメントで結合を作成することもできます。『SQL Engine Reference』では、これら SQL ステートメントおよび結合ビューの最適化の方法について説明しています。
FROM 句に各テーブル名またはビュー名を表示することによって、テーブルからデータを取得できます。1 つまたは複数の結合条件を指定するには、WHERE 句を使用します。結合条件では、1 つのテーブルから列の値を参照する式を、別のテーブルから列の値を参照する式と比較します。
データが正しく正規化されると、ほとんどの結合は指定されたキー値に基づいて値を関連付けます。それにより、参照整合性の関係でデータを抽出できます。たとえば、どの教授がどのクラスを教えているかを知りたい場合、Faculty ID に基づいて結合を作成できます。Faculty ID は、Class テーブル内の外部キーであり、また、Person テーブル内の主キーです。
SELECT DISTINCT Class.Name, Person.Last_Name
FROM Class, Person, Faculty
WHERE Class.Faculty_ID = Person.ID
AND Class.Faculty_ID = Faculty.ID;
この例では、共通の列 Faculty ID の共通の値に基づいて 2 つのテーブルを結合します。
また、データ型の列の間で数値の比較を行うことでもテーブルを結合できます。たとえば、<、>、または = を使用して列を比較できます。Faculty テーブルの以下の自己結合は、各教職員より給与が高いすべての教職員を識別します。このため、Faculty テーブルに含まれているレコードよりかなり多くのレコードが生成されます。
SELECT A.ID, A.Salary, B.ID, B.Salary
FROM Faculty A, Faculty B
WHERE B.Salary > A.Salary;
日付や時刻などの同様の比較を行えば、多数の有効かつ意味のある結果を生成できます。
列を結合する場合は、可能であれば同じデータ型の列を選択します。たとえば、2 つの NUMERIC 列を比較する方が、NUMERIC 列を INTEGER 列と比較するより効率的です。2 つの列が同じデータ型でなく、ともに数値または文字列であれば、Zen は両方のテーブルをスキャンし、結合条件を結果に対する制限として適用します。
WHERE 句で文字列型の列を使用する場合、結合条件の 1 つの列を計算の文字列の列とすることができます。そうすれば、複数の文字列を連結し、結合条件でそれらの文字列を別のテーブルからの 1 つの文字列と比較することができます。
Zen が結合を処理する方法は、結合条件にインデックス列が含まれているかどうかにより異なります。
• インデックスとして定義されている列が結合条件に含まれている場合、パフォーマンスは向上します。インデックスで対応するテーブル内の行をソートする場合、Zen は制限句の条件に合う行だけを選択します。
• 結合条件にインデックスとして定義されている列が含まれていない場合、パフォーマンスは低下します。Zen は各テーブルの各行を読んで制限句の条件に合致する行を選択します。パフォーマンスを向上するために、結合を実行する前にテーブルのうちの 1 つでインデックスを作成することができます。これは特に、クエリが頻繁に実行するクエリである場合に有効です。
テーブルと他のテーブルとの結合
SELECT ステートメントを使用して結合を指定するには、FROM 句 を使用して関連するテーブルを一覧表示し、WHERE 句を使用して結合の条件と制限を指定します。以下の例では、エイリアスを使用してステートメントの単純化も行います。
SELECT Student_ID, Class_ID, Name
FROM Enrolls e, Class cl
WHERE e.Class_ID = cl.ID;
次の例では、3 つのテーブルを結合します。
SELECT p.ID, Last_Name, Name
FROM Person p, Enrolls e, Class cl
WHERE p.ID = e.Student_ID AND e.Class_ID = cl.ID;
次の例では、英語で 3.0 より低い成績をとった学生のリストを取得します。
SELECT First_Name, p.Last_Name
FROM Person p, Student s, Enrolls e, Class cl
WHERE s.ID = e.Student_ID
AND e.Class_ID = cl.ID
AND s.ID = p.ID
AND cl.Name = 'ACC 101'
AND e.Grade < 3.0;
この例では、WHERE 句の最初の 3 つの条件で 4 つのテーブル間の結合を指定します。次の 2 つの条件は、ブール演算子 AND で接続された制限句です。
ビューとテーブルの結合
ビューを 1 つまたは複数のテーブルと結合するには、FROM 句にビュー名を取り込みます。指定するビューには、1 つのテーブルまたはいくつかの結合されたテーブルから列を取り込むことができます。
結合のタイプ
Zen は、等結合、不等号結合、ヌル結合、カルテシアン結合、自己結合、左外部結合、右外部結合、および全外部結合をサポートします。
結合の構文の詳細については、『SQL Engine Reference』の次のトピックを参照してください。
等結合
等結合は、2 つの結合列を等価と定義するときに発生します。以下のステートメントは、等結合を定義します。
SELECT First_Name, Last_Name, Degree, Residency
FROM Person p, Student s, Tuition t
WHERE p.ID = s.ID AND s.Tuition_ID = t.ID;
不等号結合
比較演算に基づいてテーブルを結合できます。不等号結合では以下の演算子を使用できます。
以下の WHERE 句は、≧ 演算子を使用する結合を示しています。
SELECT Name, Section, Max_Size, Capacity, r.Building_Name, Number
FROM Class cl, Room r
WHERE Capacity >= Max_Size;
カルテシアン結合
カルテシアン結合は、あるテーブル内の各行を別のテーブル内の各行に関連付けます。Zen は、一方のテーブルの各行に対しもう一方のテーブルのすべての行を読み取ります。
大きなテーブルでは、カルテシアン結合に時間がかなりかかる可能性があります。Zen は、このタイプの結合を行うために以下の行数を読み取らなければならないからです。
(あるテーブル内の行数) * (ほかのテーブル内の行数)
たとえば、あるテーブルに 600 行含まれており、もう 1 つのテーブルに 30 行含まれている場合、Zen は各テーブルのカルテシアン結合を作成するのに 18,000 行を読み取ります。
以下のステートメントは、サンプル データベース内の Person テーブルと Course テーブルにカルテシアン結合を生成します。
SELECT s.ID, Major, t.ID, Degree, Residency, Cost_Per_Credit
FROM Student s, Tuition t#
自己結合
自己結合では、FROM 句でテーブル名を何回も指定できます。自己結合を指定する場合は、テーブル名の各インスタンスにエイリアスを割り当て、Zen が結合でテーブルの各発生セグメントを区別できるようにします。
以下の例では、Jason Knibb という人と同じ州に定住所がある人のすべてをリストします。このクエリは、ID、名前、名字、現在の電話番号、電子メール アドレスを返します。
SELECT p2.ID, p2.First_Name, p2.Last_Name, p2.Phone, p2.EMail_Address
FROM Person p1, Person p2
WHERE p1.First_Name = 'Jason' AND p1.Last_Name = 'Knibb' and p1.Perm_State = p2.Perm_State
左部、右部、完全外部結合
外部結合の詳細については、『
SQL Engine Reference』に記載されています。
SELECT および
JOIN を参照してください。
サブクエリ
ネストされたクエリとも呼ぶサブクエリは、以下のうちの 1 つの中に含まれている SELECT ステートメントです。
• 別の SELECT ステートメントの WHERE 句または HAVING 句。
• UPDATE または DELETE ステートメントの WHERE 句。
サブクエリを使用すると、ネストされた SELECT ステートメントの出力に SELECT、UPDATE または DELETE ステートメントの結果の基準を置くことができます。
相関関係を持つサブクエリ以外のサブクエリを発行すると、Zen はステートメント全体を構文解析し、最も内側のサブクエリを最初に実行します。最も内側のサブクエリの結果を次のレベルのサブクエリに対する入力として使用し、以下同様に行います。
サブクエリで使用できる式の詳細については、『SQL Engine Reference』を参照してください。
サブクエリの制限
WHERE 句のサブクエリは、検索基準の一部になります。SELECT、UPDATE、および DELETE ステートメントでサブクエリを使用する場合は、以下の制限が適用されます。
• サブクエリを小かっこで囲む必要があります。
• サブクエリに UNION 句を含めることはできません。
• 外部クエリの WHERE 句で ANY、ALL、EXISTS、または NOT EXISTS キーワードを使用しない限り、サブクエリの選択リストには列名の式を 1 つしか組み込めません。
• TOP と LIMIT は、1 つのクエリまたはサブクエリ内でいずれか一方を使用できますが、両方は使用できません。
ステートメントにいくつかのレベルのサブクエリをネストできます。ネストできるサブクエリ数は、Zen が使用できるメモリ量で決定されます。
相関サブクエリ
相関サブクエリには、外部クエリの FROM 句のテーブルから列を参照する WHERE または HAVING 句が含まれています。この列を相関列と呼びます。外部クエリからの結果と比較してサブクエリからの結果をテストするか、クエリの中の特定値の有無をテストするには、相関サブクエリを使用しなければなりません。
相関列は外部クエリから取得されるため、外部クエリの行がフェッチされるたびにその値は変化します。次に Zen はこの変化した値に基づいて内部クエリの式を評価します。
以下の例に、教室で実際に使用される時間より多い履修単位時間を持つコースの名前を示します。
SELECT c.Name, c.Credit_Hours
FROM Course c
WHERE c.Name IN
(SELECT c1.Name
FROM Class cl
WHERE c.Name = cl.Name AND c.Credit_Hours >
(HOUR (Finish_Time - Start_Time) + 1))#
上記のステートメントは、パフォーマンスを向上させるために簡単なクエリに書き換えることができます。
SELECT c.Name, c.Credit_Hours
FROM Class c1, Course c
WHERE c1.Name = c.Name AND c.Credit_Hours >
(HOUR (Finish_Time - Start_Time) + 1)#
制限句
制限句は、演算子と式からなる ASCII テキスト文字列です。制限句は、ビューの列の値に対する選択基準を指定し、ビューに取り込む行数を制限します。WHERE や HAVING などの句の構文では、制限句を使用しなければなりません。制限句は、以下の条件を指定できます。
• 制限条件-列の値を参照する式を、同じテーブル内の列の値を参照する定数または別の式と比較します。
• 結合条件-あるテーブルの列の値を参照する式を、別のテーブルの列の値を参照する式と比較します。
制限句には、複数の条件を含めることができます。制限句には、データベース内のほかのテーブルの内容に検索基準を置いている SELECT サブクエリも含めることができます。サブクエリを含む条件には、EXISTS、NOT EXISTS、ALL、ANY および SOME キーワードまたは IN 範囲演算子を含めることができます。
SELECT、UPDATE または DELETE ステートメント内の WHERE または HAVING 句を使用して、制限句を指定できます。
次の制限句の例は、制限句の要素を図示しています。
![](../prog_gde/images/Sqlrtrv.png)
制限句演算子
制限句は 3 つのタイプの演算子を使用できます。
• ブール演算子 – 制限句の条件を連結します。
• 条件演算子 – 式を連結して条件を形成します。条件演算子は、関係演算子または範囲演算子とすることができます。
• 式演算子 – 2 つの式を連結して別の式を作ります。式の演算子は、算術演算子または文字列演算子のいずれかです。
ブール演算子
ブール演算子は、論理条件を指定します。
条件演算子
条件演算子は、関係演算子または範囲演算子とすることができます。
• 関係演算子-列の値を別の列の値または定数と比較します。列の値が True であれば、Zen はその行を選択します。
• 範囲演算子 - 列の値をその列の指定された範囲の値と比較します。列の値が True であれば、制限を通過し、Zen はその行を選択します。
次の表は関係演算子を示します。
次の表は条件演算子を示します。
IN 演算子と NOT IN 演算子を使用すると、第 2 の式は列名または定数の代わりにサブクエリとすることができます。
式の演算子
式の演算子を使用して、算術演算子または文字列演算子で計算列の式を作成できます。詳細については、
関数を参照してください。
制限句の例
以下の例では、制限句演算子のいくつかを実証します。
OR と 等号(=)
以下の例では、関係 EQUAL TO 演算子とブール OR 演算子を使用します。また、State 列の値が Texas または New Mexico であるすべての行を選択します。
SELECT Last_Name, First_Name, State
FROM Person
WHERE State = 'TX' OR State = 'NM'#
IN
以下の例では、IN 演算子を使用します。これにより、名が Bill と Roosevelt のレコードがテーブル Person から選択されます。
SELECT * FROM Person WHERE First_name IN
('Roosevelt', 'Bill')#
LIKE
以下の例では、LIKE 演算子を使用します。
SELECT ID, First_Name, Last_Name, Zip
FROM Person
WHERE Zip LIKE '787%';
この例では、Person テーブルから ZIP コードが '787' で始まるレコードを取得します。
関数
一度データベースにデータを取り込むと、データに対して関数(集計関数)を使用して、列値のセットに結果を返すことができます。または、1 つまたは複数のパラメーターを入力として受け入れ、スカラー関数を使用して、1 つの値を返すことができます。
集計関数
集計関数は、一連の列の値に対する 1 つの結果を返す関数です。Zen では、次の表に示す集計関数を使用できます。
これらの各関数の詳細については、『SQL Engine Reference』を参照してください。
集計関数への引数
AVG 関数と SUM 関数の場合、関数への引数は数値列名でなければなりません。COUNT 関数、MIN 関数、および MAX 関数は、数値列または非数値列に結果を示すことができます。
集計関数の参照をネストすることはできません。たとえば、以下の参照は有効ではありません。
SUM(AVG(Cost_Per_Credit))
以下の例に示すように、式で集計関数を使用できます。
AVG(Cost_Per_Credit) + 20
グループ集計関数への引数として式を使用することもできます。たとえば、以下の式は有効です。
AVG(Cost_Per_Credit + 20)
集計関数は、ヌル列の値を有効値として扱います。たとえば、40 行のデータと 5 行のヌル値を含むテーブルで、COUNT 関数は 45 を返します。
DISTINCT キーワードを使用して、Zen がすべてのヌル列の値を 1 つの値として扱うようにすることができます。以下の例では、Grade 列で列の平均値を計算します。
AVG(DISTINCT Grade)
DISTINCT キーワードは、AVG 関数、COUNT 関数および SUM 関数に影響を与えます。このキーワードは、MIN 関数と MAX 関数に影響を与えません。
集計関数の規則
以下のように、SELECT ステートメントで集計関数を使用できます。
• 選択リストの項目
• HAVING 句
一般に、GROUP BY 句を含む SELECT ステートメントで集計関数を使用して、ある行のグループの集計値を算定します。ただし、SELECT ステートメントに GROUP BY 句が含まれておらず、その句で集計関数を使用したい場合、選択リストのすべての項目は集計関数でなければなりません。
SELECT ステートメントに GROUP BY 句が含まれている場合、GROUP BY 句に指定する列は、集計関数でなく単一の列である選択項目でなければなりません。ただし、GROUP BY 句にも示されていない選択項目はすべて集計関数でなければなりません。
以下の例では、各学生が支払った金額を決定できる結果テーブルを返します。
SELECT Student_ID, SUM(Amount_Paid)
FROM Billing
GROUP BY Student_ID;
GROUP BY 句で使用される HAVING 句に集計関数を組み込むこともできます。GROUP BY 句を持つ HAVING 句を使用すると、Zen から返される行のグループが制限されます。Zen は GROUP BY 句で指定された各行グループの列に対して集計関数を実行し、グループ化列の値が等しい行セットごとに 1 つの結果を返します。
以下の例では、Zen は 15 時間を超える履修単位時間で現在受講登録されている学生についてのみ行グループを返します。
SELECT Student_ID, SUM(Credit_Hours)
FROM Enrolls e, Class cl, Course c
WHERE e.Class_ID = cl.ID AND cl.Name = c.Name
GROUP BY Student_ID
HAVING SUM(Credit_Hours) > 15;
スカラー関数
CONCAT や CURDATE のようなスカラー関数は、1 つまたは複数のパラメーターを入力として受け入れ、1 つの値を返します。たとえば、LENGTH 関数は文字列の列の値の長さを返します。式で計算列を使用できる Zen ステートメントでスカラー関数を使用できます。
使用できる式演算子のタイプは、関数が返す結果のタイプにより異なります。たとえば、関数が数値を返す場合、算術演算子を使用できます。関数が文字列を返す場合、文字列演算子を使用できます。
スカラー関数をネストできますが、以下の例に示すように、ネストされた各関数は次のレベルのスカラー関数へ対応するパラメーターとしての結果を返します。
SELECT RIGHT (LEFT (Last_Name, 3), 1)
FROM Person;
Zen はまず、LEFT 関数を実行します。Last Name 列の値が Baldwin である場合、LEFT 関数から生ずる文字列は Bal です。この文字列は RIGHT 関数のパラメーターで、この関数は文字列の右端の文字として「l」を返します。
数値を計算する計算列の中に数値結果を返すスカラー関数を使用できます。文字列値を式として別の文字列関数へ返すスカラー関数も使用できますが、文字列の結果の合計長は 255 バイト以内でなければなりません。
Zen で使用できるスカラー関数の詳細については、『
SQL Engine Reference』の
ビット演算子を参照してください。