FROM (SQL)
構文
SELECT ... FROM [optimize-option] table-ref
[ [AS] t-alias ]
[, [LATERAL] table-ref [ [AS] t-alias] ] [,...]
引数
引数 | 説明 |
---|---|
optimize-hint | オプション — クエリ最適化オプションを指定する、単一キーワード、または空白で区切られた一連のキーワード。詳細は、"クエリでの最適化ヒントの指定" を参照してください。 |
table-ref | データの取得元の 1 つ以上のテーブル、ビュー、テーブル値関数、またはサブクエリ。コンマで区切られたリストとしてか、JOIN 構文で指定されます。JOIN 構文でのビューの使用にはいくつかの制限が適用されます。サブクエリは、括弧で囲んで指定できます。 |
AS t-alias | オプション — テーブル名のエイリアス。有効な識別子である必要があります。AS キーワードは省略可能で、これの有無に関係なくエイリアスを指定できます。 |
LATERAL | オプション — FROM 節で指定された以前のテーブルをラテラル参照できるようにします。詳細は、"LATERAL キーワード" を参照してください。 |
概要
FROM 節は、SELECT 文内でデータを照会する 1 つ以上のテーブル (もしくはビューまたはサブクエリ) を指定します。テーブル・データが照会されていない場合には、以下のように、FROM 節はオプションです。
複数のテーブルは、コンマで区切られたリスト、または他の JOIN 構文によって区切られたリストとして指定されます。各テーブル名には、オプションとしてエイリアスを指定できます。
テーブル名のエイリアスは、SELECT 文で複数のテーブルのフィールド名を指定するときに使用されます。FROM 節で複数のテーブルを指定している場合は、SELECT の select-item 節で、フィールドを tablename.fieldname の形式で指定することにより、どのテーブルのフィールドを対象とするのかを示すことができます。この場合、テーブル名は長い名前が多いので、短いテーブル名のエイリアスを指定すると便利です (t-alias.fieldname)。
以下の例は、テーブル名のエイリアスの使用方法を示します。
SELECT e.Name,c.Name
FROM Sample.Company AS c,Sample.Employee AS e
AS キーワードは省略できます。このキーワードは、互換性とわかりやすい表記のためのものです。
テーブル参照に対するスキーマ名の指定
table-ref 名は、修飾 (schema.tablename) でも未修飾 (tablename) でもかまいません。未修飾のテーブル名 (またはビュー名) のスキーマ名は、次のように、スキーマ検索パスまたはシステム全体の既定のスキーマ名を使用して指定されます。
-
スキーマ検索パスが指定されている場合、指定スキーマで一致テーブル名が検索されます。
-
スキーマ検索パスが指定されていないか、スキーマ検索パスで一致が生成されない場合、システム全体の既定のスキーマ名が使用されます。
テーブルの結合
FROM 節で複数のテーブル名を指定すると、InterSystems SQL はこれらのテーブルに対して結合操作を実行します。実行される結合のタイプは、join キーワード句またはテーブル名の各ペアの間の記号で指定します。2 つのテーブル名がコンマで区切られているときは、交差結合が実行されます。結合のさまざまなタイプと構文の詳細は、"JOIN" を参照してください。
結合が実行される順序は、SQL クエリ・オプティマイザによって自動的に決定され、クエリにテーブルがリストされる順序には基づきません。必要に応じて、クエリ・オプティマイザのオプションを指定して結合を実行する順序を制御できます。
最初の 2 つの SELECT 文は、2 つの個別のテーブルに対する行カウントを示し、3 番目の例は、両方のテーブルを指定する SELECT に対する行カウントを示しています。後者の例は、より大きなテーブル、デカルト積になります。この場合、1 番目のテーブルのそれぞれの行が、2 番目のテーブルのそれぞれの行に一致します。これは、Cross Join という処理です。
SELECT COUNT(*)
FROM Sample.Company
SELECT COUNT(*)
FROM Sample.Vendor
SELECT COUNT(*)
FROM Sample.Company,Sample.Vendor
CROSS JOIN 構文を明示的に使用しても同じ動作を実行できます。
SELECT COUNT(*)
FROM Sample.Company CROSS JOIN Sample.Vendor
多くの場合、Cross Join の広範囲なデータ重複は望ましくありません。その他の Join タイプをお勧めします。
SELECT 文で WHERE 節を指定すると、交差結合が実行され、WHERE 節の述語によって結果セットが決まります。これは ON 節を指定した INNER JOIN を実行することと同じです。したがって、以下の 2 つの例は同じ結果を返します。
SELECT p.Name,p.Home_State,em.Name,em.Office_State
FROM Sample.Person AS p, Sample.Employee AS em
WHERE p.Name %STARTSWITH 'E' AND em.Name %STARTSWITH 'E'
SELECT p.Name,p.Home_State,em.Name,em.Office_State
FROM Sample.Person AS p INNER JOIN Sample.Employee AS em
ON p.Name %STARTSWITH 'E' AND em.Name %STARTSWITH 'E'
FROM table-ref リストで明示的な結合構文を指定すると (コンマを使用するのではない)、別のタイプの結合操作を実行できます。詳細は、"JOIN" を参照してください。
クエリ最適化オプション
既定で、InterSystems SQL クエリ・オプティマイザは、高度で柔軟性の高いアルゴリズムを使用して結合オペレーションや複数のインデックスを含む複雑なクエリのパフォーマンスを最適化します。ほとんどの場合、これらの既定によってパフォーマンスが最適化されます。ただし、インターシステムズのサポート窓口にお問い合わせいただくと、クエリ最適化についての解釈を 1 つ以上指定することで、クエリ・オプティマイザに “ヒント” を与えるように指示されることがあります。これらのヒントは、FROM で optimize-hint 引数を使用して指定します。複数の最適化ヒントは空白で区切り、任意の順序で指定できます。詳細は、"クエリでの最適化ヒントの指定" を参照してください。
FROM 節内の単純な SELECT 文、CREATE VIEW ビュー定義の SELECT 文、またはサブクエリ SELECT 文で optimize-hint FROM 節キーワードを使用できます。
FROM 節におけるテーブル値関数
SELECT Name,DOB FROM Sample.SP_Sample_By_Name('A')
以下のダイナミック SQL の例では、同じテーブル値関数を指定します。%Execute() メソッドを使用して ? 入力パラメータにパラメータ値を指定します。
SET myquery="SELECT Name,DOB FROM Sample.SP_Sample_By_Name(?)"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus = tStatement.%Prepare(myquery)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
SET rset = tStatement.%Execute("A")
DO rset.%Display()
WRITE !,"End of A data",!!
SET rset = tStatement.%Execute("B")
DO rset.%Display()
WRITE !,"End of B data"
テーブル値関数は、SELECT 文または DECLARE 文の FROM 節でのみ使用できます。テーブル値関数名は、スキーマ名で修飾することも、未修飾 (スキーマ名なし) にすることもできます。未修飾の名前は、既定のスキーマを使用します。SELECT 文の FROM 節では、テーブル名を使用できる箇所ならどこでもテーブル値関数を使用できます。ビューまたはサブクエリでも使用でき、コンマ区切りのリストまたは明示的な JOIN 構文を使用して他の table-ref 項目に結合できます。
テーブル値関数は、INSERT、UPDATE、または DELETE 文で直接使用することはできません。ただし、テーブル値関数を指定するこれらのコマンドのためのサブクエリを指定することはできます。
InterSystems SQL は、テーブル値関数のための EXTENTSIZE、またはテーブル関数列のための SELECTIVITY は定義しません。
FROM 節のサブクエリ
FROM 節ではサブクエリを指定できます。これは、ストリーム化されたサブクエリとして知られています。サブクエリは、JOIN 構文での使用や AS キーワードを使用したオプションのエイリアス割り当てなども含めて、テーブルと同様に扱われます。FROM 節には、複数のテーブル、ビュー、およびサブクエリを任意の組み合わせで含むことができますが、"JOIN" で説明されている JOIN 構文の制約を受けます。
サブクエリは括弧で囲まれます。以下の例は、FROM 節のサブクエリを示しています。
SELECT name,region
FROM (SELECT t1.name,t1.state,t2.region
FROM Employees AS t1 LEFT OUTER JOIN Regions AS t2
ON t1.state=t2.state)
GROUP BY region
サブクエリでは TOP 節を指定できます。サブクエリには、TOP 節と組み合わせて ORDER BY 節を記述できます。
サブクエリでは SELECT * 構文を使用できます。ただし、FROM 節から得られるのは数値としての式なので、SELECT * を指定したサブクエリでは 1 つの列のみが生成されるようにする必要があります。
サブクエリ内の結合を NATURAL 結合にしたり、USING 節を指定することはできません。
FROM サブクエリと %VID
FROM サブクエリが呼び出されると、このサブクエリは、返されるサブクエリ行ごとに %VID を返します。%VID は整数カウンタ・フィールドです。その値は、システムによって割り当てられる一意の非 NULL かつ非ゼロ値であり、変更することはできません。%VID は、明示的に指定された場合にのみ返されます。これはデータ型 INTEGER として返されます。%VID の値は連続した整数であるため、サブクエリが順序付きデータを返す場合はとても有意義なものになります。TOP 節と組み合わせるときには、サブクエリでは ORDER BY 節以外は使用できません。
%VID は連続した整数であるため、%VID を使用して、ORDER BY 節が使用されたサブクエリ内の項目のランキングを特定できます。以下の例では、最も新しい 10 件のレコードが Name の順にリストされますが、それらのタイムスタンプ・ランキングは %VID の値を使用して簡単に確認できます。
SELECT Name,%VID,TimeStamp FROM
(SELECT TOP 10 * FROM MyTable ORDER BY TimeStamp DESC)
ORDER BY Name
%VID の一般的な用途の 1 つは、実行内容を 1 つの表示ウィンドウに収まる行数に合致する連続したサブセットに分割して、結果セットを “ウィンドウ表示” することです。例えば、20 件のレコードを表示してから、ユーザが Enter キーを押すまで待ち、次の 20 件のレコードを表示できます。
以下の例は、%VID を使用して、結果を 10 件のレコードごとのサブセットに分割して “ウィンドウ表示” します。
SELECT %VID,* FROM
(SELECT TOP 60 Name, Age FROM Sample.Person WHERE Age > 55 ORDER BY Name)
WHERE %VID BETWEEN ? AND ?
%VID の使用の詳細は、"ビューの定義と使用" を参照してください。
LATERAL キーワード
FROM 節で以前に指定したテーブルのフィールド値をビューおよびテーブル値関数で参照できるようにすることで、LATERAL キーワードを使用して FROM 処理の順序をより明示的に制御できます。このようなラテラル参照は、サブクエリまたはテーブル値関数で生成する行に影響します。
LATERAL キーワードを指定したサブクエリまたはテーブル値関数では、ラテラル参照するフィールドが指定値と見なされます。ラテラル参照先のフィールドは、必ず同じ FROM 節にある以前の FROM アイテムから得られます。
FROM サブクエリに先行して記述した LATERAL キーワードは、クエリの中で意味的に先行する FROM アイテムのフィールドを、このサブクエリが参照する可能性があることを示します。このようなラテラル参照先のフィールドは、LATERAL が指定された FROM サブクエリよりも先に処理されます。
テーブル値関数に先行して記述した LATERAL キーワードは、以前の FROM アイテムのフィールドを、テーブル値関数で使用できることを示しています。このコンテキストでは、このキーワードはオプションであり、このような参照をテーブル値関数で使用するとラテラル結合が暗黙的に適用されます。
オプションの FROM 節
SELECT 項目リストで (直接的にも間接的にも) テーブル・データが参照されていない場合、FROM 節はオプションです。この種類の SELECT は、関数、演算子式、定数またはホスト変数からデータを返す場合に使用できます。テーブル・データを参照しないクエリでは、以下のようになります。
-
FROM 節が省略された場合には、TOP キーワードの値に関係なく、返されるデータ行は最大でも 1 つです。TOP が 0 の場合には、データが返されません。DISTINCT 節は無視されます。特権は不要です。
-
FROM 節を指定する場合には、現在のネームスペースに既存のテーブルを指定する必要があります。そのテーブルが参照されない場合でも、テーブルに SELECT 特権を設定する必要があります。TOP 節または DISTINCT 節を指定した場合、あるいはその節を WHERE 節または HAVING 節で制限した場合を除き、返される同一データ行の数は、指定したテーブルの行数と等しくなります。DISTINCT 節を指定すると、出力が単一のデータ行に限定されます。TOP キーワードを指定すると、出力は TOP 値で指定された行数に制限されます。TOP が 0 の場合には、データが返されません。
FROM 節を使用した場合でも使用しない場合でも、後続の節 (WHERE、GROUP BY、HAVING または ORDER BY) は指定できます。結果を返すかどうか、または同一の結果行をいくつ返すかを決定する場合には、WHERE 節または HAVING 節を使用できます。FROM 節を指定していない場合でも、これらの節はテーブルを参照できます。GROUP BY 節または ORDER BY 節を指定することもできますが、これらの節は無意味です。
以下は、テーブル・データを参照しない SELECT 文の例です。どちらの例も、情報を 1 行返します。
以下の例では、FROM 節が省略されています。DISTINCT キーワードは不要ですが、指定することはできます。SELECT 節は許可されていません。
SELECT 3+4 AS Arith,
{fn NOW} AS NowDateTime,
{fn DAYNAME({fn NOW})} AS NowDayName,
UPPER('MixEd cASe EXPreSSioN') AS UpCase,
{fn PI} AS PiConstant
以下の例では、FROM 節が含まれています。DISTINCT キーワードは、1 つのデータ行を返すために使用されています。FROM 節で参照するテーブルは、有効なテーブルである必要があります。ここでは ORDER BY 節が許可されていますが無意味です。ORDER BY 節では、有効な選択項目の別名を指定する必要があります。
SELECT DISTINCT 3+4 AS Arith,
{fn NOW} AS NowDateTime,
{fn DAYNAME({fn NOW})} AS NowDayName,
UPPER('MixEd cASe EXPreSSioN') AS UpCase,
{fn PI} AS PiConstant
FROM Sample.Person
ORDER BY NowDateTime
以下の例は両方とも、結果を返すかどうかを決定するために WHERE 節を使用しています。最初の例では FROM 節が含まれており、DISTINCT キーワードを使用して 1 つのデータ行を返します。2 番目の例では FROM 節が省略されているため、返されるデータ行は最大でも 1 つです。どちらの場合でも、WHERE 節で参照するテーブルは、SELECT 特権を設定した有効なテーブルである必要があります。
SELECT DISTINCT
{fn NOW} AS DataOKDate
FROM Sample.Person
WHERE FOR SOME (Sample.Person)(Name %STARTSWITH 'A')
SELECT {fn NOW} AS DataOKDate
WHERE FOR SOME (Sample.Person)(Name %STARTSWITH 'A')
関連項目
-
SQL クエリの最適化