SQL初心者なのでtableをJOINするときの文法で、別名をつける記法があることを知らない、しかもASは省略できるってよ

# 疑問

```sql
SELECT
    `foo`.`id` AS t0_r0,
    `foo`.`xxx` AS t0_r1,
    `assets`.`id` AS t1_r0,
    `assets`.`name` AS t1_r1,
    `assets`.`type` AS t1_r2,
    `assets_bar`.`id` AS t3_r0,
    `assets_bar`.`name` AS t3_r1,
    `assets_bar`.`type` AS t3_r2,
    `foo_assets`.`id` AS t4_r0,
    `foo_assets`.`xxx` AS t4_r1,
    `foo_assets`.`asset_id` AS t4_r2,
    `foo_assets`.`bar_id` AS t4_r3,
FROM
    `foo`
    LEFT OUTER JOIN
        `assets`
    ON  `assets`.`id` = `foo`.`asset_id`
    LEFT OUTER JOIN
        `bar`
    ON  `bar`.`id` = `foo`.`bar_id`
    LEFT OUTER JOIN
        `number_indices`
    ON  `number_indices`.`number_hash` = `bar`.`number_hash`
    AND `number_indices`.`type` IN('AIndex', 'BIndex')
    LEFT OUTER JOIN
        `assets` `assets_bar`
    ON  `assets_bar`.`id` = `number_indices`.`asset_id`
    LEFT OUTER JOIN
        `foo` `foo_assets`
    ON  `foo_assets`.`asset_id` = `assets_bar`.`id`
```

若干省略しましたが上のようなSQLをみたとき、`assets_bar`も`foo_assets`というtable名らしきものが見えます。

しかしDBを眺めてもそんな名前のtableは見当たりません。なのにクエリを実行すると実行できてしまいます。

一体どこから来たものなのでしょうか？

# 手がかり

```sql
    LEFT OUTER JOIN
        `assets`
    ON  `assets`.`id` = `foo`.`asset_id`
```

```sql
    LEFT OUTER JOIN
        `assets` `assets_bar`
    ON  `assets_bar`.`id` = `number_indices`.`asset_id`
```

この2つをよく見比べるとどっちにも`assets`がみえます。それに

```
`assets` `assets_bar`
```

という間のスペース、なにか気になります。

それにSELECTしているカラム名を見ると

```sql
SELECT
    `foo`.`id` AS t0_r0,
    `foo`.`xxx` AS t0_r1,
    `assets`.`id` AS t1_r0,
    `assets`.`name` AS t1_r1,
    `assets`.`type` AS t1_r2,
    `assets_bar`.`id` AS t3_r0,
    `assets_bar`.`name` AS t3_r1,
    `assets_bar`.`type` AS t3_r2,
    `foo_assets`.`id` AS t4_r0,
    `foo_assets`.`xxx` AS t4_r1,
    `foo_assets`.`asset_id` AS t4_r2,
    `foo_assets`.`bar_id` AS t4_r3,
```

`assets` `assets_bar`の2つってやっぱり似てますよね・・・？

# 謎解き

こんなとき見るべきは規格書です。

まずSQLのjoinの文法を見ます。ISOから規格書買ってくるのは面倒なので、適当なところから拾ってます、ご容赦を。

> [7.12.1 Specification format and rules for joined tables : Hitachi Advanced Database SQL Reference](http://itdoc.hitachi.co.jp/manuals/3000/3000650490e/HSQL0172.HTM)
>
> ```
> joined-table ::= {cross-join|qualified-join|(joined-table)}
>  
>  
>   cross-join ::= table-reference CROSS JOIN table-primary
>  
>   qualified-join ::= table-reference [{INNER|{LEFT|RIGHT|FULL} [OUTER]}] JOIN [join-method-specification] table-reference join-specification
>     join-specification ::= ON search-condition
> ```

構文と上のSQLを見比べると


```
`assets` `assets_bar`
```

は`table-reference`に該当しそうです。

> <dl>
> <dt><i>table-reference</i>:</dt>
> <dd>Specifies a table or a joined table to be joined. For details about table references, see <a href="http://itdoc.hitachi.co.jp/manuals/3000/3000650490e/HSQL0169.HTM">7.11 Table reference</a>.</dd>

7.11章を見に行くように言われたので見に行きます。

> [7.11.1 Specification format for table references : Hitachi Advanced Database SQL Reference](http://itdoc.hitachi.co.jp/manuals/3000/3000650490e/HSQL0170.HTM)
>
> ```
> table-reference ::= {table-primary | joined-table}
>  
>   table-primary ::= {table-name [[AS] correlation-name][index-specification]
>                  | query-name [[AS] correlation-name]
>                  | derived-table [[AS] correlation-name [(derived-column-list)]]
>                  | table-function-derived-table [AS] correlation-name (table-function-column-list)
>                  | (joined-table)}
> ```

`table-reference`は`table-primary`もしくは`joined-table`のことと定義されています。

`table-primary`の定義を見るとその中に`table-name [[AS] correlation-name][index-specification]`というのがあります。これが求めていたものでしょうか？

> <dl>
> <dt><i>table-name</i>:</dt>
> <dd>Specifies the table from which to retrieve data. For rules on specifying a table name, see (2) Table name specification format.
> <ul>
>   <li>To retrieve data from a dictionary table or system table, specify the schema name MASTER.</li>
>   <li>If an archivable multi-chunk table is specified, accesses to the location table and system table (STATUS_CHUNKS) occur. At this time, locked resources are secured for the system table (STATUS_CHUNKS). For details about locks, see Locking in the HADB Setup and Operation Guide.</li>
> </ul></dd>
> <dt>[AS] correlation-name:</dt>
> <dd>Specifies a name assigned to separately identify a table for one of the following purposes:
> <ul>
> <li>To join a table to itself</li>
> <li>To reference a column of the same table inside a subquery</li>
> </ul></dd>

`table-name`は文字通りデータを取ってこようとするテーブル名のことで、`[AS] correlation-name`っていうのテーブルを識別するためのもので、は自己結合したりサブクエリの中で同じテーブルのカラムを参照するのに使うと書かれています。`[AS]`というからにはASは省略できるってことなのでしょう。

# 結論


```sql
    LEFT OUTER JOIN
        `assets` `assets_bar`
    ON  `assets_bar`.`id` = `number_indices`.`asset_id`
```


```sql
    LEFT OUTER JOIN
        `assets` AS `assets_bar`
    ON  `assets_bar`.`id` = `number_indices`.`asset_id`
```

この2つのSQLは等価であり、`assets_bar`というのは`ON`以下で指定した条件で`assets`テーブルをLEFT OUTER JOINしたときのテーブルを識別する別名であるということがいえます。

別名ですから本当にそういう名前のテーブルが有るってわけじゃないので見つからないのも当然なのでした。