2010年11月12日金曜日

Tutorial D の拡張と要約 - 値の計算と集約

Tutorial D でリレーショナル代数」のつづき

拡張

既存の属性を元に計算した結果を関係に追加する。 SQL では SELECT 句においてカラムに演算子を適用することに相当。Date によると、

「オリジナルで定義されたリレーショナル代数の範囲を超えてしまう」

(データベース実践講義, p101より)

ために 「拡張」 と呼ばれる。

例えば、「人」 に対して、

  • 年齢の 2 倍
  • 男性であるかどうか?

となる属性を関係に追加したい場合は、

extend persons 
  add(age * 2 as DoubleAge, gender = 1 as isMale)

311-12-2010CropperCapture[3]

(対象のデータベースはこちら)

 

拡張の後に制限

上記の書き方を見ると SQL の方が簡単に思えるが、Tutorial D の拡張により返されるのは 「関係」 であるため、返される値に対してスムーズに制限を適用できる。

先ほどの結果に対して、

  • 年齢を 2 倍したら 50 以上で、かつ、男性である人

を抽出したい場合、

extend persons
  add(age * 2 as DoubleAge, gender = 1 as isMale)
  where DoubleAge >= 50 and isMale

と書くことができる。

 

要約

「人」 の要素数を知りたい場合は、

summarize persons 
  add(count() as pCount)

411-12-2010CropperCapture[4]

最高齢の人を求めるには、対象となる属性 age を max に与える。

summarize persons 
  add(max(age) as pMax)

511-12-2010CropperCapture[5]

定義されている要約は summary を参照。

 

特定の基準で要約 - by

SQL で言う GROUP BY に相当するもの。

例えば、性別ごとの人数を得るには、

summarize persons 
  by {gender}
    add(count() as pCount)

611-12-2010CropperCapture[6]

per を使っても上記と同じ結果が得られる。

summarize persons
  per(persons {gender})
    add(count() as pCount)

ただし、これだと書くのが面倒なので、上記のように by が定義されているのかな。

 

他の関係変数と組み合わせる - per

per は別の関係変数と組み合わせたときに有用。

例えば、「割当て」 を 「人」 の id ごとにカウントしたい場合に by を使うと、

summarize assignments 
  by {p_id}
    add(count() as pCount)

811-12-2010CropperCapture[8]

当然ながら、「割当て」 がされてない人は表示されない。

これに対し、「人」 を基準にして 「割当て」 を要約すると、

summarize assignments 
  per((persons rename(id as p_id)) {p_id})
    add(count() as pCount)

 711-12-2010CropperCapture[7]

「割当て」 がされてない人も表示される。

by と per の定義については、summarizeper_or_by を参照。

Tutorial D で外部キーの定義 - 整合性制約で記述」につづく