« 2025年8月にリリースした曲 / DTM / GarageBand | トップページ | Siriの日本語音声2の女性の声を利用して、今際の国のアリスの「ゲームを開始します」、「ゲームオーバー」っぽい音声Loopを作るテスト »

2025年9月30日 (火) / Author : Hiroshi Sekiguchi.

帰ってきた! 標準はあるにはあるが癖の多いSQL #19 - c_alias の癖(おまけ)

書き漏らしていたことに気づいたので、
今日のテーマは、

帰ってきた! 標準はあるにはあるが癖の多いSQL #18 - t_alias と c_alias にも癖が出る

の癖のおまけw

Oracle Database、PostgreSQL、MySQLの表エイリアスと列エイリアスの文法の癖の違いを思い出してもらった上で、今日の列エイリアスの癖も合わせて覚えておくと良いかもしれません。

とは言え、サブクエリーで該当構文を使うことはあまり無さそうな気はします。
どちらかというと、表値コンストラクターの記述で効果的な構文だと思うので。。。(表値コンストラクターネタは、別エントリーにて)


まず、帰ってきた! 標準はあるにはあるが癖の多いSQL #18 - t_alias と c_alias にも癖が出るの列エイリアスの癖の復習から。


インラインビュー(サブクエリー)の列エイリアスを以下のような構文で書けるDBと書けないDBを見てみましょう。

SELECT
*
FROM
(
SELECT
empno
, 'a'
FROM
emp
) t01 (empno, dummy_col)
;


Oracle Database 23ai ver. 23.8
Oracle Databaseではこの構文は許されていませんよね! 表値コンストラクターがサポートされた流れで通常のサブクエリーでも使えるようになるかもしれませんが、、、、。

SCOTT@localhost:1521/freepdb1> select banner_full from v$version;

BANNER_FULL
--------------------------------------------------------------------------------
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04

SCOTT@localhost:1521/freepdb1> l
1 SELECT
2 *
3 FROM
4 (
5 SELECT
6 empno
7 , 'a'
8 FROM
9 emp
10 ) t01 (empno, dummy_col)
11*
COTT@localhost:1521/freepdb1> /
) t01 (empno, dummy_col)
*
行10でエラーが発生しました。:
ORA-03048: SQL予約語'('は、'..., 'a'
FROM
emp
) t01 'の後では構文的に有効ではありません ヘルプ:
https://docs.oracle.com/error-help/db/ora-03048/

MySQL 8.4
MySQLでは可能でしたよね。

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.4.6 |
+-----------+

mysql> SELECT
-> *
-> FROM
-> (
-> SELECT
-> empno
-> , 'a'
-> FROM
-> emp
-> ) t01 (empno, dummy_col)
-> ;
+-------+-----------+
| empno | dummy_col |
+-------+-----------+
| 7782 | a |
| 7839 | a |

...略...

| 7844 | a |
| 7900 | a |
+-------+-----------+
14 rows in set (0.01 sec)

PostgreSQL 17.5
PostgreSQLでも可能ですよね。
ここまでは、帰ってきた! 標準はあるにはあるが癖の多いSQL #18 - t_alias と c_alias にも癖が出るでも書いてました。

perftestdb=> SELECT
perftestdb-> *
perftestdb-> FROM
perftestdb-> (
perftestdb(> SELECT
perftestdb(> empno
perftestdb(> , 'a'
perftestdb(> FROM
perftestdb(> emp
perftestdb(> ) t01 (empno, dummy_col)
perftestdb-> ;
empno | dummy_col
-------+-----------
7369 | a
7499 | a

...略...

7902 | a
7934 | a
(14 rows)


で、書き忘れていたのは以降の癖。

以下のように、複数ある列の一方だけのつもりで、列エイリアスを書いたら。。。。どうなるか。

どうなると思います?

SELECT
*
FROM
(
SELECT
empno
, 'a'
FROM
emp
) t01 (dummy_col)
;


Oracle Database 23ai 23.8
Oracle Databaseではそもそもサブクエリーに対するこの構文は許されていないのでエラーです。

SCOTT@localhost:1521/freepdb1> l
1 SELECT
2 *
3 FROM
4 (
5 SELECT
6 empno
7 , 'a'
8 FROM
9 emp
10 ) t01 (dummy_col)
11*
10:30:52 SCOTT@localhost:1521/freepdb1> /
) t01 (dummy_col)
*
行10でエラーが発生しました。:
ORA-03048: SQL予約語'('は、'..., 'a'
FROM
emp
) t01 'の後では構文的に有効ではありません ヘルプ:
https://docs.oracle.com/error-help/db/ora-03048/


MySQL 8.4.5
おお! 変化しましたね。 MySQLでは全列定義しないとエラーになるようです。全列のエイリアスを指定するか、しないかのどちらかということですね! わかりやすい気がしますね。これ。

mysql> SELECT
-> *
-> FROM
-> (
-> SELECT
-> empno
-> , 'a'
-> FROM
-> emp
-> ) t01 (dummy_col)
-> ;
ERROR 1353 (HY000): In definition of view, derived table or common table expression, SELECT list and column names list have different column counts


PostgreSQL 17.5
では、真打w PostgreSQL。PostreSQLでは一部でも構文エラーにはならない!!!! まじか、じゃ、指定した列エイリアスはどの列を対象にするの?!!!!!!

サブクエリーの列数と同数の列エイリアスを指定しない場合、SELECTリストの列順に対応させているだけのようですね!。この例では、empno列と、無名の列の2列がありますが、列エイリアスで置き換えられたのは、最初のempno列!です

エラーにならないだけに、ちょっと注意が必要な癖ですよね!
エラーにはならないことが、正しいというわけでもないので。。。このケースでは意図しない列名を列エイリアスで置換してしまっているわけで。。MySQLのようにエラーにしてくれた方が嬉しいのではないだろうか。

perftestdb=> SELECT
perftestdb-> *
perftestdb-> FROM
perftestdb-> (
perftestdb(> SELECT
perftestdb(> empno
perftestdb(> , 'a'
perftestdb(> FROM
perftestdb(> emp
perftestdb(> ) t01 (dummy_col)
perftestdb-> ;
dummy_col | ?column?
-----------+----------
7369 | a
7499 | a

...略...

7902 | a
7934 | a
(14 rows)


最後に、サブクエリーで、各列毎に列エイリアスを指定した方が可読性は良いと考えているので、その比較用w
(前述した列エイリアス構文が、その威力を発揮するのは表値コンストラクターを利用する場合ぐらいになるだろうと思っています)


こんな感じでも、

SELECT
*
FROM
(
SELECT
empno
, 'a' AS dummy_col
FROM
emp
) t01
;

下記のような場合でも読みやすいとおもいます:)

SELECT
*
FROM
(
SELECT
empno AS empno
, 'a' AS dummy_col
FROM
emp
) t01
;


Oracle

SCOTT@localhost:1521/freepdb1> l  1  SELECT
2 *
3 FROM
4 (
5 SELECT
6 empno
7 , 'a' AS dummy_col
8 FROM
9 emp
10 ) t01
11*
SCOTT@localhost:1521/freepdb1> /

EMPNO DUMMY_COL
---------- ---------
7369 a
7499 a

...略...

7902 a
7934 a

14行が選択されました。

SCOTT@localhost:1521/freepdb1> l
1 SELECT
2 *
3 FROM
4 (
5 SELECT
6 empno AS empno
7 , 'a' AS dummy_col
8 FROM
9 emp
10 ) t01
11*
SCOTT@localhost:1521/freepdb1> /

EMPNO DUMMY_COL
---------- ---------
7369 a
7499 a

...略...

7902 a
7934 a

14行が選択されました。


MySQL

mysql> SELECT
-> *
-> FROM
-> (
-> SELECT
-> empno
-> , 'a' AS dummy_col
-> FROM
-> emp
-> ) t01
-> ;
+-------+-----------+
| empno | dummy_col |
+-------+-----------+
| 7782 | a |
| 7839 | a |

...略...

| 7844 | a |
| 7900 | a |
+-------+-----------+
14 rows in set (0.00 sec)

mysql> SELECT
-> *
-> FROM
-> (
-> SELECT
-> empno AS empno
-> , 'a' AS dummy_col
-> FROM
-> emp
-> ) t01
-> ;
+-------+-----------+
| empno | dummy_col |
+-------+-----------+
| 7782 | a |
| 7839 | a |

...略...

| 7844 | a |
| 7900 | a |
+-------+-----------+
14 rows in set (0.00 sec)


PostgreSQL

perftestdb=> SELECT
perftestdb-> *
perftestdb-> FROM
perftestdb-> (
perftestdb(> SELECT
perftestdb(> empno
perftestdb(> , 'a' AS dummy_col
perftestdb(> FROM
perftestdb(> emp
perftestdb(> ) t01
perftestdb-> ;
empno | dummy_col
-------+-----------
7369 | a
7499 | a

...略...

7902 | a
7934 | a
(14 rows)

perftestdb=> SELECT
perftestdb-> *
perftestdb-> FROM
perftestdb-> (
perftestdb(> SELECT
perftestdb(> empno AS empno
perftestdb(> , 'a' AS dummy_col
perftestdb(> FROM
perftestdb(> emp
perftestdb(> ) t01
perftestdb-> ;
empno | dummy_col
-------+-----------
7369 | a
7499 | a

...略...

7902 | a
7934 | a
(14 rows)


癖にも色々あります。
PostgreSQLのケースではエラーにならないからといって、だいじょーふだ!!、とは言えないタイプも癖もあます。

別エントリーで予定している表値コンストラクターではこの列エイリアスの構文が重要だったりするので、混乱しないよう、
効果的な場所で使っていく必要はありそうだなぁと思っているところ:)
Oracleのように、そもそも表値エイリアスでしか使えない場合は悩む必要もないわけですが。(いまのところ)


やっと東京も東北方面の気温に近づきつつある。。気もするw

では、また。


Enjoy SQL and 癖 !





関連エントリー
標準はあるにはあるが癖の多いSQL 全部俺 #1 Pagination
標準はあるにはあるが癖の多いSQL 全部俺 #2 関数名は同じでも引数が逆の罠!
標準はあるにはあるが癖の多いSQL 全部俺 #3 データ型確認したい時あるんです
標準はあるにはあるが癖の多いSQL 全部俺 #4 リテラル値での除算の内部精度も違うのよ!
標準はあるにはあるが癖の多いSQL 全部俺 #5 和暦変換機能ある方が少数派
標準はあるにはあるが癖の多いSQL 全部俺 #6 時間厳守!
標準はあるにはあるが癖の多いSQL 全部俺 #7 期間リテラル!
標準はあるにはあるが癖の多いSQL 全部俺 #8 翌月末日って何日?
標準はあるにはあるが癖の多いSQL 全部俺 #9 部分文字列の扱いでも癖が出る><
標準はあるにはあるが癖の多いSQL 全部俺 #10 文字列連結の罠(有名なやつ)
標準はあるにはあるが癖の多いSQL 全部俺 #11 デュエル、じゃなくて、デュアル
標準はあるにはあるが癖の多いSQL 全部俺 #12 文字[列]探すにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #13 あると便利ですが意外となかったり
標準はあるにはあるが癖の多いSQL 全部俺 #14 連番の集合を返すにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #15 SQL command line client
標準はあるにはあるが癖の多いSQL 全部俺 #16 SQLのレントゲンを撮る方法
標準はあるにはあるが癖の多いSQL 全部俺 #17 その空白は許されないのか?
標準はあるにはあるが癖の多いSQL 全部俺 #18 (+)の外部結合は方言
標準はあるにはあるが癖の多いSQL 全部俺 #19 帰ってきた、部分文字列の扱いでも癖w
標準はあるにはあるが癖の多いSQL 全部俺 #20 結果セットを単一列に連結するにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #21 演算結果にも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #22 集合演算にも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #23 複数行INSERTにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #24 乱数作るにも癖がある
標準はあるにはあるが癖の多いSQL 全部俺 #25 SQL de Fractalsにも癖がある:)
標準はあるにはあるが癖の多いSQL 全部俺 おまけ SQL de 湯婆婆やるにも癖がでるw
帰ってきた! 標準はあるにはあるが癖の多いSQL #1 SQL de ROT13 やるにも癖が出るw
帰ってきた! 標準はあるにはあるが癖の多いSQL #2 Actual Plan取得中のキャンセルでも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #3 オプティマイザの結合順評価テーブル数上限にも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #4 Optimizer Traceの取得でも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #5 - Optimizer Hint でも癖が多い
帰ってきた! 標準はあるにはあるが癖の多いSQL #6 - Hash Joinの結合ツリーにも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #7 - Hash Joinの実行計画にも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #8 - Hash Joinさせるにも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #9、BOOLEAN型にも癖が出る
帰ってきた! 標準はあるにはあるが癖の多いSQL #10、BOOLEAN型にも癖が出る(後編)
帰ってきた! 標準はあるにはあるが癖の多いSQL #10、BOOLEAN型にも癖が出る(後編)の おまけ - SQL*PlusのautotraceでSQL Analysis Reportが出力される! (23ai〜)
帰ってきた! 標準はあるにはあるが癖の多いSQL #11 - 引用符にも癖がでるし、NULLのソート構文にも癖がある!(前編)
帰ってきた! 標準はあるにはあるが癖の多いSQL #12 - 引用符にも癖がでるし、NULLのソート構文にも癖がある!(後編)ー 列エイリアスの扱いにも癖がある!
帰ってきた! 標準はあるにはあるが癖の多いSQL #13 - コメント書くにも癖がある
帰ってきた! 標準はあるにはあるが癖の多いSQL #14 - コメントを書く位置にも癖がでる (SQL Clientにも癖がある)
帰ってきた! 標準はあるにはあるが癖の多いSQL #15 - 実行計画でスカラー副問合せの見せ方にも癖がでる
帰ってきた! 標準はあるにはあるが癖の多いSQL #16 - FROM句のインラインビューのエイリアスにもクセがある(必須だったり、任意だったり)
帰ってきた! 標準はあるにはあるが癖の多いSQL #17 - ANY_VALUE() ってなかなかいいじゃん、癖無さそう!
帰ってきた! 標準はあるにはあるが癖の多いSQL #18 - t_alias と c_alias にも癖が出る

| |

コメント

コメントを書く