2.5.1 表式の形式と規則
- 〈この項の構成〉
(1) 機能
検索の対象となる一つ又は複数の表を指定します。また,表を検索,又は結合するときの条件(探索条件やグループ分け)が指定できます。表式は副問合せ及び問合せ指定中,又は1行SELECT文中に指定します。
(2) 形式
FROM 表参照〔,表参照〕… 〔WHERE 探索条件〕 〔GROUP BY 値式〔,値式〕…〕 〔HAVING 探索条件〕
(3) オペランド
(a) 副問合せを使用しない場合
検索する,表,問合せ名,導出表,又は結合表を指定します。表参照については,「表参照」を参照してください。
探索条件を省略すると,表(指定した表,結合表,導出表,及びWITH句中の導出問合せ式から問合せ名として導出された表)から導き出されるすべての行が検索されます。
探索条件中に,埋込み変数を指定できます。PREPARE文で前処理をするSELECT文中では,埋込み変数の代わりに?パラメタを指定します。SQL手続き中では,SQL変数又はSQLパラメタを使用します。Java手続き中については,マニュアル「HiRDB UAP開発ガイド」のJDBCドライバを参照してください。
-
〔GROUP BY 値式〔,値式〕…〕
グループ分けでは,GROUP BY句で指定した値式のすべての結果の値が同一の行をそれぞれ一つのグループとして分け,その結果をグループごとに1行にして出力します。
選択式には,グループ分けする列の名称,集合関数,定数,若しくはこれらを一次子とする値式,又はグループ分けをする値式だけ指定できます。すなわち,グループ分けする値式(値式が列指定の場合を除く)を一次子として含む値式は指定できません。なお,GROUP BY句で指定した値式をグループ化列といいます。
GROUP BY句についての規則を次に示します。
-
グループ分けの条件となる列にナル値を持つ行がある場合は,ナル値を同じ値として扱いグループ分けします。
-
GROUP BY句に指定する値式は,同じ形式の値式を重複して指定できません。
-
GROUP BY句に指定する値式は,集合関数を含むことはできません。
-
GROUP BY句に指定する値式は,ウィンドウ関数を含むことはできません。
-
GROUP BY句に指定する値式中には,コンポネント指定を含むことはできません。
-
GROUP BY句に指定する値式中には,繰返し列は指定できません。
-
GROUP BY句に指定する値式中には,予備列は指定できません。
-
GROUP BY句に指定する値式には,副問合せを含むことはできません。
集合関数(AVG,MAX,MIN,SUM,COUNT及びCOUNT_FLOAT)を指定できます。
HAVING句についての規則を次に示します。
-
集合関数以外の探索条件には,グループ分けした値式だけ指定できます。
-
グループ分けした値式は,GROUP BY句で指定した値式と全く同じ形式にしてください。
-
探索条件を省略した場合は,すべてのグループを出力します。
(b) 副問合せを使用する場合
検索する,表,問合せ名,導出表,又は結合表を指定します。表参照については,「表参照」を参照してください。
FROM句に複数の表を追加した場合,各表から1行ずつ組み合わせて指定した表の順序に連結した行がFROM句の結果の表の行になり,その行数は各表の行数の積になります。
副問合せ中の探索条件中の列指定は,副問合せの外側で指定した表の列を参照できます。
問合せが入れ子の場合,内側の問合せから外側の問合せで指定している表(の列)を参照することを,外への参照をするといいます。
WHERE句についての規則を次に示します。
-
WHERE句にCOUNT(*)又はCOUNT_FLOAT(*)は指定できません。
-
HAVING句に属するWHERE句中だけ,WHERE句に集合関数を指定できます。
-
HAVING句に属するWHERE句に集合関数を指定した場合,その集合関数中の列指定は,そのHAVING句に先行するFROM句に指定した表を参照(外への参照)してください。
-
GROUP BY句に列指定以外の値式を指定した問合せ指定のWHERE句の副問合せには,GROUP BY句に列指定以外の値式を指定できません。
-
〔GROUP BY 値式〔,値式〕…〕
GROUP BY句に指定する列は,そのGROUP BY句がある表式中のFROM句で指定している表を参照してください。
グループ分けでは,GROUP BY句で指定した値式のすべての結果の値が同一の行をそれぞれ一つのグループとして分け,その結果をグループごとに1行にして出力します。
選択式には,グループ分けする列の名称,集合関数,定数,若しくはこれらを一次子とする値式,又はグループ分けをする値式だけ指定できます。すなわち,グループ分けする値式(値式が列指定の場合を除く)を一次子として含む値式は指定できません。なお,GROUP BY句に指定した値式をグループ化列といいます。
また,値式に列指定以外を指定した場合,選択式に指定したスカラ副問合せ中からそのグループ化列を参照することはできません。
GROUP BY句についての規則を次に示します。
-
グループ分けの条件になる列にナル値を持つ行がある場合,ナル値同士を同じ扱いとしてグループ分けします。
-
GROUP BY句に指定する値式は,同じ形式の値式を重複して指定できません。
-
GROUP BY句に指定する値式は,集合関数を含むことはできません。
-
GROUP BY句に指定する値式は,ウィンドウ関数を含むことはできません。
-
GROUP BY句に指定する値式中には,コンポネント指定を含むことはできません。
-
GROUP BY句に指定する値式中には,繰返し列は指定できません。
-
GROUP BY句に指定する値式中には,予備列は指定できません。
-
GROUP BY句に指定する値式には,副問合せを含むことはできません。
HAVING句は,先行するGROUP BY句,WHERE句,又はFROM句の結果,得られる各グループを選択する条件を指定します。ただし,GROUP BY句を指定しないと,WHERE句,又はFROM句の結果はグループ化列を持たない一つのグループになります。
HAVING句についての規則を次に示します。
-
HAVING句中に指定した探索条件の結果が真となるグループが選択されます。
-
HAVING句を省略すると,先行するGROUP BY句,WHERE句,又はFROM句の結果のすべてのグループが選択されます。
-
グループ分けした値式は,GROUP BY句で指定した値式と全く同じ形式にしてください。
-
HAVING句中に列指定を指定する場合,次のようにしてください。
-
その表式中のFROM句の表を参照するか,又は外側の表式中のFROM句の表を参照(外への参照)する
-
その表式中のFROM句の表を参照している場合,グループ化列(GROUP BY句で指定した値式)か,又は集合関数の引数中に指定する
-
(4) 共通規則
-
探索条件中に埋込み変数を指定できます。
-
PREPARE文で前処理をするSQL文中では,埋込み変数の代わりに?パラメタを指定します。
(5) 結合についての規則
一つのFROM句に複数の表,又は問合せ名を指定した検索(複数の表にわたる検索)を結合といいます。
-
FROM句に,結合するすべての表,又は問合せ名を指定します。WHERE句に結合条件がない場合は,結合する各表から一つずつ行を取り出して組み合わせたものが結果になります。例えば,l行,m行,n行から成る三つの表を無条件で結合するとl×m×n個の行になります。
-
結合する列にナル値を持つ行は,どの行に対しても条件を満足しません。
-
同じ列名の列がある表,又はWITH句の導出問合せ式から問合せ名として導出される表を結合する場合は,その列を指定するときに表名,又は相関名を付けてその列を一意にして指定します。
-
結合できる(FROM句に指定できる)実表,FROM句の導出表の延べ数は,最大128個です。
また,一つのSQL文中に指定できる実表の延べ数(副問合せで指定する実表の延べ数も含む)は最大128個です。相関名の延べ数は,最大129個です。
1トランザクションで同時にアクセスできる表数は,システム定義のpd_max_access_tablesオペランドの値までです。pd_max_access_tablesオペランドのデフォルト値は64のため,必要に応じてpd_max_access_tablesオペランドの値を変更してください。pd_max_access_tablesオペランドの値を増やすとメモリ所要量が増加します。詳細は,マニュアル「HiRDB システム定義」のpd_max_access_tablesオペランドを参照してください。
名前付きの導出表(ビュー表又はWITH句の問合せ)を使用した場合,その名前付きの導出表一つに対する表の結合数は,ビュー定義文中,又はWITH句中の導出問合せ式で指定している実表,及びFROM句の導出表の延べ数になります。同様に,その名前付きの導出表一つに対するSQL文中で指定した表数は,ビュー定義文中,又はWITH句中の導出問合せ式で指定した実表の延べ数になります。その名前付きの導出表一つに対するSQL文中で指定した相関名数は,ビュー定義文中,又はWITH句中の導出問合せ式で指定した相関名数になります。
また,ビュー定義文中,又はWITH句中の導出問合せ式に集合演算を指定して導出した名前付きの導出表を,SQL文中で指定し,かつ,その名前付きの導出表が内部導出表となる条件をどれも満たさない場合,表数,相関名数は次のようになります。
表数=
(導出問合せ式中で指定した実表の延べ数)
+((導出問合せ式中の集合演算数+1)
×(副問合せ中の実表の延べ数))
相関名数=
(導出問合せ式中で指定した相関名の延べ数)
+((導出問合せ式中の集合演算数+1)
×(副問合せ中の相関名の延べ数))
なお,ビュー定義文中の導出問合せ式の制限項目については,「CREATE 〔PUBLIC〕VIEW(ビュー定義,パブリックビュー定義)」を参照してください。また,WITH句中の導出問合せ式の制限項目については,「問合せ式」を参照してください。また,名前付きの導出表が内部導出表となる条件は,「内部導出表」を参照してください。
-
内部導出表を作成する問合せ指定では,内部導出表の作成対象となる一つの名前付きの導出表同士の結合は指定できません。内部導出表を作成する条件については,「内部導出表」を参照してください。
(6) GROUP BY句,及びHAVING句についての規則
-
ビュー定義中,又はWITH句中の導出問合せ式のGROUP BY句には,列指定の値式を指定してください。
-
問合せ指定にウィンドウ関数を指定した場合,GROUP BY句及びHAVING句は指定できません。
(7) 留意事項
-
次のどれかの条件を満たす場合,HiRDBが作業表を作成することがあります。
-
複数の表を結合している
-
GROUP BY句を指定している
-
表一次子にビュー表又は問合せ名を指定し,内部導出表を作成している(内部導出表については,「内部導出表」を参照してください)
このとき,作業表の行長によっては,上記の処理が制限されることがあります。作業表の行長については,マニュアル「HiRDB システム導入・設計ガイド」を参照してください。
-
(8) 指定例(動的SELECT文中で表式を指定した場合)
SELECT SUM(ZSURYO) FROM ZAIKO WHERE TANKA >= (SELECT AVG(TANKA) FROM ZAIKO)
(9) 使用例
表Aは商品の単価の表,表Bは受注のあった商品の受注量の表,表Cは先月受注のあった商品の受注量の表です。
-
単価が200より大きい商品の商品コード,単価,及び受注量を取得します。
SELECT A.SCODE,TANKA,JSURYO FROM A LEFT OUTER JOIN B ON A.SCODE = B.SCODE WHERE TANKA > 200
-
すべての商品コード,及び単価と,受注量が40以上の受注量を取得します。
SELECT A.SCODE,TANKA,JSURYO FROM A LEFT OUTER JOIN B ON A.SCODE = B.SCODE AND JSURYO >= 40
-
すべての商品コード,及び単価と,単価が400以上の商品の受注量を取得します。
SELECT A.SCODE,TANKA,JSURYO FROM A LEFT OUTER JOIN B ON A.SCODE = B.SCODE AND TANKA >= 400
-
単価が500以下の商品について,商品コード及び単価と,40以上の今月の受注量,30以下の先月の受注量を取得します。
SELECT A.SCODE,A.TANKA,B.JSURYO,C.SENRYO FROM A LEFT OUTER JOIN B ON A.SCODE=B.SCODE AND B.JSURYO >= 40 LEFT OUTER JOIN C ON A.SCODE=C.SCODE AND C.SENRYO <= 30 WHERE A.TANKA <= 500
-
すべての商品コード及び単価と,単価が400以下の商品の今月の受注量と,先月の受注量を取得します。
SELECT A.SCODE,A.TANKA,B.JSURYO,C.SENRYO FROM A LEFT OUTER JOIN B ON A.SCODE = B.SCODE AND A.TANKA <= 400 LEFT OUTER JOIN C ON A.SCODE = C.SCODE AND A.TANKA <= 400
-
すべての商品コードと,各商品の今月の受注量の,先月の受注量に対する比率を求めます。ただし,今月又は先月に受注のなかった商品については,ナル値を出力します。
SELECT A.SCODE,100.0*B.JSURYO/C.SENRYO FROM A LEFT OUTER JOIN (B INNER JOIN C ON B.SCODE=C.SCODE) ON A.SCODE = B.SCODE
-
すべての商品コード及び単価と,今月の受注量と,先月の受注量から,今月と先月の売上を取得します。
SELECT SCODE,TANKA*JSURYO,TANKA*SENRYO FROM(SELECT A.SCODE,A.TANKA,B.JSURYO,C.SENRYO FROM A LEFT OUTER JOIN B ON A.SCODE = B.SCODE LEFT OUTER JOIN C ON A.SCODE = C.SCODE) AS DT1(SCODE,TANKA,JSURYO,SENRYO)