■前回まで

/* SQL分析用フォーマット */

typedef struct ST_SQL {

    char Crud[16+1];         /* "Insert", "Select", "Update", "Delete" */

    int DistinctFlg;         /* Distinct:有⇒1, 無⇒0                 */

    char *ColumnsStr;        /* 抽出カラム文字列                       */

    char *ColumnsOStr[1024]; /* 抽出カラムOriginal(項目別)             */

    char *ColumnsEStr[1024]; /* 抽出カラムEnglish(項目別)              */

    char *ColumnsAStr[1024]; /* 抽出カラム別名(項目別)                 */

    char FromOStr[128+1];    /* 抽出元Original                         */

    char FromEStr[64+1];     /* 抽出元English                          */

    char FromAStr[128+1]     /* 抽出元別名                             */

    char *WhereStr;          /* Where句の中身                          */

    char *GroupByStr;        /* グループ化項目                         */

    char *HavingStr;         /* グループ化前処理条件                   */

    char *OrderByStr;        /* ソート項目                             */

}

 

■ここまでは、単体selectの構造しか表現できてない

つまり?

SQLとは、selectの組み合わせで成り立つものです。

そこで問題になるのが、select同士の上下関係ですね。

 

■selectの上下関係とは

分かりやすいところから行きましょう。

 

selectの最終目的は何でしょうか。

ある結果を画面やらファイルやらに出力したい。

それが最終的なアウトプットですね?

その最終結果を、数字で1としましょう。

1は最強、最終で、それより大きな数字の階層となるselectを「下位階層」と考えましょう。

 

■集合演算子

union、union allはどうでしょうか。

select同士の集合体、それが単純加算であっても単純加算後の重複行削除後であっても。

つまり、unionつなぎは、同階層です。

同じ脈絡で、minus, except, intersectも階層で言えば同列と言えます。

つまり、集合対象の階層とunion, union all, minus, except, intersectは、同階層に存在します。

 

例えば、集合対象の階層が1ならば、集合する本人も1で良いのですね。

 

■多数並列

しかし、後に述べる結合やサブクエリもそうですが、集合対象が一つとは限りません。

同じ階層であってもとりあえずは区別しておく必要があります。

従って、例えば、最上位階層(1)となるselect文に対して集合演算子でつながるselect文は、階層は同じ1ですが、1-?

階層番号にサブ番号が必要となります。

 

この事は、後述に述べるサブクエリ、結合に関しても同じ脈絡なので、覚えておいてください。

 

■結合・サブクエリ

 結合の概念の基本は「テーブル同士を並列につなぎ合わせる」ですから、本来は結合相手と同等階層です。

しかしながら、結合本人がテーブルではなく、一時領域であれば、結果的に設計書上の表記は下位階層になります。

 サブクエリの場合は、where句に従属するものなので、基本的に1段階、階層が下がります。

 

■結果として構造体の変化

以下の様になりました。

青字⇒追加

大分、盛大になってきましたね。

でも、かなりのところまで来ました。

階層がつくと、記載表現が豊かになります。

 

/* SQL分析用フォーマット */

typedef struct ST_SQL {

    int KNo;                 /* 階層No                                 */

    int KNoSub;              /* 階層サブNo                             */

    int LKNo[64];            /* リンク元階層No(最上位の場合、0)        */

    int LKNoSub[64];         /* リンク元階層サブNo(最上位の場合、0)    */

    char JoinMthd[64];       /* 結合方法(join、サブクエリ)             */

    char *JoinKey            /* 結合キー                               */

    char Crud[16+1];         /* "Insert", "Select", "Update", "Delete" */

    int DistinctFlg;         /* Distinct:有⇒1, 無⇒0                 */

    char *ColumnsStr;        /* 抽出カラム文字列                       */

    char *ColumnsOStr[1024]; /* 抽出カラムOriginal(項目別)             */

    char *ColumnsEStr[1024]; /* 抽出カラムEnglish(項目別)              */

    char *ColumnsAStr[1024]; /* 抽出カラム別名(項目別)                 */

    char FromOStr[128+1];    /* 抽出元Original                         */

    char FromEStr[64+1];     /* 抽出元English                          */

    char FromAStr[128+1]     /* 抽出元別名                             */

    char *WhereStr;          /* Where句の中身                          */

    char *GroupByStr;        /* グループ化項目                         */

    char *HavingStr;         /* グループ化前処理条件                   */

    char *OrderByStr;        /* ソート項目                             */

}

 

■上位は下位を気にする必要がない

リンク先は勝手に見られているだけなので、自分の階層意識さえあれば良い。

しかし、リンク元は、リンク先の立ち位置との相関関係が分からないと「自分が今、どこにいるのかすら分からない」となる。

従って、最上位階層のLKNo、LKNoSubはゼロであり、KNo=1である。

これは私の考えるデータモデル上、絶対原則である。

 

満足なので、本日はここら辺で。

またね^^