一応 Oracle をベースとしてのお話です。
一番の大原則は、group by で指定された列のみが select で そのまま記述できるというところです。
テーブルは通常正規化されていますから、コードに対する名称は別テーブルある事になります。
ですから、結合して名称を取り出して、その結果を:結合したキーで group by に指定した場合、
キーと名称は一対一ですが、SQL からすれば select に指定できるのは キーのほうだけです。
この場合、どうしてもその場で名称が欲しい場合は max 関数を使いますが、全体としての解決策
はいくつかあります。しかし、とりあえずこの大原則を中心に考えます。
そもそも。
select 表示データリストfrom テーブル名 と group by グループ列 と order by は、データを
処理するプロセスが違います。元のデータに直接アクセスするのが from テーブル where 条件
で、group by グループ列 having 条件は、加工処理です。order by は全ての処理が終わった後の
単純なソート処理です。
select 表示データリスト は、出力フォーマットと考えれば良いでしょう。
そう考えた場合、グループ列( 複数もあります ) を中心に加工された出力結果が仮想的なテーブル
として提供されるのが group by の結果です。グループ列 以外はグループ関数を通して出力する
ように仕様で決められていますし、それ以外の方法は矛盾が生じます( 特例とか無いので )
とまあ、理屈をこねるより group by のやってる事を自分でかわりにやってみれば解る事で、
コントロールプレイクで集計して最大値や最小値や平均やら求めるアルゴリズムは標準化できても、
はたしてただ表示したいが為に、対象となるキーにデータを付加するのは・・・
実際は、そのデータの為に保存エリアを用意する事になりますが、その時だけの都合的処理で、
仕様としての必然性に欠けますよね。
でまあ、この話はこれくらいで。
もう一つ原則的というか、騙されやすい仕様というか、グループ関数と NULL の関係です。
これは、間違いやすい落とし穴で、 NULL 同士の演算が NULL になるという SQL の原則に
のっとった上での グループ関数の挙動ですが、全て「その行は無視」が原則です。
例外は count( * ) で NULL を含む全ての行。 count( 列名 ) は NULL を除く行数。
count( distinct 列名 ) は、列名が重複しない数( つまり種類の取得 )
その他も NULL の行は無視されますが、以下は注意です。
sum( 給与 + 手当 )
給与はともかく、手当は NULL を含むという場合が想定される場合、給与 NULL は 基本給
ですから、その値が NULL という事は理由があって計算に入れる必要が無いのは矛盾しませんが、
手当が NULL の場合、給与+手当が NULL になって、計算が除外されてしまいます。
ですから、以下のように書く必要があります。
sum( 給与 + nvl( 手当,0 ) )
ですが、現実的には結局給与にも nvl しておいたほうが痛い目を見なくて済むと思います。
|
- 複数行のグループデータを1行にまとめるSQL
- テーブル設計書作成 : VBScript + Excel.Application + SQLServer
- select 社員コード,氏名,(select count(*) from 得意先マスタ where 担当者 = 社員コード) as 件数 from 社員マスタ : 件数を where で使いたい場合..
- SQL Server とそのコンポーネントのバージョンとエディションを確認
- land.to での PHP + PostgreSQLでの接続テスト
- SQL*PlusだけでCSVを作成する
- PHP と MySQL 限定で SQL インジェクションを考えた場合
- Oracle11g + Windows7 : InstantClient を使用した軽量接続 ( Win32 )
- MySQL:GPLな再配布。プログラムは無しでデータのみ追加
- MySQL5.1.4の半手動インストール(インストール場所の変更)
- Oracleエクスポートユーティリティ(expdp)パラメータ入力支援HTMLアプリケーション
- 今年もPL/SQLはFunctionから
- OracleInstantClientによる接続確認
- SYSTEMユーザからスキーマを作成、販売管理データを投入する
- BCP.EXEで自動採番列(INTIDENTITY)を持つデータの移行
- SQLExpress2005のインストールから最速設定(2)
- SQLExpress2005のインストールから最速設定(3)
- SQLExpress2005のインストールから最速設定(1)
- 【Oracle10g接続】InstantClientを使用した接続
- MySQL5.1.26をUSBメモリに入れて使用する