はじめに - SQL標準規格では
SQL標準規格によると、SQL文ではテーブル名や列名の別名を次のように指定することができることになっている。(いずれも、キーワード AS は省略可能)
SELECT t.col2 [AS] c2 FROM tbl [AS] t WHERE t.col1 = 1 UPDATE tbl [AS] t SET col2 = 2 WHERE t.col1 = 1 DELETE FROM tbl [AS] t WHERE t.col1 = 1
(ひとつ気をつけなければいけないのは、UPDATE文のSET節で指定する列名にはプレフィックスを一切書けないこと)
この別名をつける書き方について、DBMSやそのバージョンによってサポート状況が違うようなので検証してみる。
検証
前提とするテーブルはどうでもいいのだが、一応書いておく。
CREATE TABLE tbl(id VARCHAR(16) NOT NULL, name VARCHAR(16) NOT NULL)
そして、次のようなSQL文を各DBMSに対して発行してみる。
(s1) SELECT id , name FROM tbl WHERE id = '01' (s2) SELECT id i, name n FROM tbl WHERE id = '01' (s3) SELECT id AS i, name AS n FROM tbl WHERE id = '01' (s4) SELECT t.id , t.name FROM tbl t WHERE t.id = '01' (s5) SELECT t.id , t.name FROM tbl AS t WHERE t.id = '01' (u1) UPDATE tbl SET name = 'N02' WHERE id = '01' (u2) UPDATE tbl t SET name = 'N02' WHERE t.id = '01' (u3) UPDATE tbl AS t SET name = 'N02' WHERE t.id = '01' (d1) DELETE FROM tbl WHERE id = '01' (d2) DELETE FROM tbl t WHERE t.id = '01' (d3) DELETE FROM tbl AS t WHERE t.id = '01'
いずれも、「別名を一切指定しない」「キーワード AS を省略」「キーワード AS も指定」の3通りで、SELECT文は列名とテーブル名があるため全部で5通りになる。
実行した結果は次のとおり。
DBMS名 | (s1) | (s2) | (s3) | (s4) | (s5) | (u1) | (u2) | (u3) | (d1) | (d2) | (d3) |
---|---|---|---|---|---|---|---|---|---|---|---|
DB2 9.1 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
DB2 9.5 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
DB2 9.7 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
Oracle 10g | ○ | ○ | ○ | ○ | × | ○ | ○ | × | ○ | ○ | × |
PostgreSQL 8.0 | ○ | × | ○ | ○ | ○ | ○ | × | × | ○ | × | × |
PostgreSQL 8.1 | ○ | × | ○ | ○ | ○ | ○ | × | × | ○ | × | × |
PostgreSQL 8.2 | ○ | × | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
PostgreSQL 8.3 | ○ | × | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
PostgreSQL 8.4 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
PostgreSQL 9.0 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
MySQL 4.1 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | × | × |
MySQL 5.0 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | × | × |
MySQL 5.1 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | × | × |
MySQL 5.5 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | × | × |
Firebird 2.1 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
Firebird 2.5 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
Derby 10.5.3.0 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
SQLite 3.6.14.2 | ○ | ○ | ○ | ○ | ○ | ○ | × | × | ○ | × | × |
SQLServer 2005 | ○ | ○ | ○ | ○ | ○ | ○ | × | × | ○ | × | × |
SQLServer 2008 | ○ | ○ | ○ | ○ | ○ | ○ | × | × | ○ | × | × |
H2 1.2 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
H2 1.3 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
HSQLDB 1.8.1 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
この結果から‥
- SELECT文でテーブル名の別名にキーワードASが使えないのはOracle 10gだけ
- PostgreSQLは、途中まで、列名の別名にキーワードASを使えない
- PostgreSQLは、バージョンによって仕様がちょいちょい違う
- DELETE文でのテーブル名の別名指定は、サポートしていないDBMSも結構多い
余談
なんでこんなことを調べようとしたかというと、とあるPostgreSQL(何)で、上記(d3)にあたるクエリを書いていて、あっちでは動くのにそっちでは動かないということがあって、調べてみたら、動かないほうはバージョンが古いものだったという‥