質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

select した際に、列の別名に列コメントを指定できるデータベースはありますか?またはその方法 ※PL/SQL, プログラムでの動的生成は除く

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 4,892

tec

score 9

例えば以下のようなテーブルがあった場合に、
select した結果を以下のようにしたいです。

create table Employee (
  CompanyId 文字列型, -- 会社ID
  EmployeeId 文字列型, -- 社員ID
  EmployeeName 文字列型, -- 社員名
)


結果

会社ID 社員ID 社員名
00001 A000000001 田中

もちろん手動で列名をエイリアスで定義したら出来ますが、
列のコメントを取得して、それをエイリアスにする方法がありますでしょうか?

select
  CompanyId as 会社ID
, EmployeeId as 社員ID
, EmployeeName as 社員名
from Employee

ではなくて、、、

select
  CompanyId as [Employee.CompanyIdのコメント]
, EmployeeId as [Employee.EmployeeIdのコメント]
, EmployeeName as [Employee.EmployeeNameのコメント]
from Employee

として、[]内をSQL結果等から引っ張って設定したいです。

追記

データベースの種類やバージョンの指定等は特にありません。
ただ、PL_SQLや、プログラム上でSQLを構築する方法ではなくて、
一回のSQLでエイリアス名の設定を含めて取得することが出来るのかを知りたかったのです。
※そのため、create table の構文を、「varchar2」指定していたのを「文字列型」と編集しました。

例えばSQLServerの書き方だと、以下の方法でEmployeeテーブルの列のコメントを取得できましたが、
「extended_properties.value」の値を、エイリアス名として指定した上でSQLで取得できるのか?ということです。

select
     tbl.name    as TABLE_NAME
    ,col.name    as COLUMN_NAME
    ,ep.value  as COMMENT
from sys.tables tbl
inner join sys.columns col
  on col.object_id = tbl.object_id
inner join sys.extended_properties ep
  on ep.major_id = col.object_id
 and ep.minor_id = col.column_id
where
    tbl.name = 'Employee'


結果

TABLE_NAME COLUMN_NAME COMMENT
Employee CompanyId 会社ID
Employee EmployeeId 社員ID
Employee EmployeeName 社員名
-- エイリアス部分を一回のSQLでなんらかの方法で指定する方法があるのか知りたいのです。
select
  CompanyId as [case data.COLUMN_NAME='CompanyId' then data.COMMENT else '' end]
, EmployeeId as [if(data.COLUMN_NAME="EmployeeId") data.COMMENT]
, EmployeeName as [data.COMMENT]
from Employee,
(
    select
         tbl.name    as TABLE_NAME
        ,col.name    as COLUMN_NAME
        ,ep.value  as COMMENT
    from sys.tables tbl
    inner join sys.columns col
      on col.object_id = tbl.object_id
    inner join sys.extended_properties ep
      on ep.major_id = col.object_id
     and ep.minor_id = col.column_id
    where
        tbl.name = 'Employee'
) data

追記②
やってみたこと@SQLServer

with t1 (c1, c2, c3)
as(
    select
      max(case when col.column_id = 1 then ep.value end)
    , max(case when col.column_id = 2 then ep.value end)
    , max(case when col.column_id = 3 then ep.value end)
    from sys.tables tbl
    inner join sys.columns col
      on col.object_id = tbl.object_id
    inner join sys.extended_properties ep
      on ep.major_id = col.object_id
     and ep.minor_id = col.column_id
    where
        tbl.name = 'Employee'
    group by
       tbl.name
)
select
  t1.c1
, t1.c2
, t1.c3
from t1

union all

select
  CompanyId
, EmployeeId
, EmployeeName
from Employee

結果

c1 c2 c3
会社ID 社員ID 社員名
00001 A000000001 田中
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SE-studying-now

    2018/08/30 11:43

    どのSQLでどのバージョンかで実現方法が変わることもあります。本文に追記頂ければと思います。

    キャンセル

  • tec

    2018/08/30 12:01

    コメントありがとうございます。特にDBの指定やバージョンも何もありませんが、一回のSQLで取得できるか?ということが知りたかったのです。

    キャンセル

  • nandymak

    2019/09/20 07:13

    何故その様なことをする必要があるかを記載すれば妙案が提示されるかもしれません。

    キャンセル

回答 2

0

varchar2型とありますから Oracle でしょうけど、同じSQLでもデータベースによって方言が大きいですから、どのデータベースを使うのかを質問のタグで明示したり、バージョンも明記した方が適切なコメントが付き易いです。

本題で、カラムの定義は USER_TAB_COLUMNS
カラムのコメントは USER_COL_COMMENTS を参照します。
コメントを列の別名とするときはダブルクォートで囲みましょう。

追記
データベースはOracleを前提として、
通貨コード のテーブル定義を利用。

Excelで1行目にコメントを使いたいものと想定。sqlplus から
--テーブル名は置換変数で
DEFINE tbl=CURRENCIES

SET HEADING OFF
SET PAGESIZE 0
SELECT DISTINCT
'COLUMN ' || TC.COLUMN_NAME || ' HEADING "' || CM.COMMENTS || '"' AS "COLUMN"
FROM USER_TABLES TA
INNER JOIN USER_TAB_COLUMNS TC
ON  TC.TABLE_NAME = TA.TABLE_NAME
INNER JOIN USER_TAB_COLUMNS TC
ON  TC.TABLE_NAME = TA.TABLE_NAME
LEFT OUTER JOIN USER_COL_COMMENTS CM
ON  CM.TABLE_NAME  = TC.TABLE_NAME
AND CM.COLUMN_NAME = TC.COLUMN_NAME
WHERE
TA.DROPPED = 'NO' -- except trash box, since oracle10.1.0
AND TA.TABLE_NAME = '&&tbl'
;
-- の結果をリダイレクト(sqlplusで再実行)
SET COLSEP ','
SPOOL &&tbl..csv
SELECT * FROM &&tbl ;
SPOOL OFF

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/30 13:28

    回答ありがとうございます。
    DBに関しては特に指定はありませんでした。
    Oracleでは列のエイリアスに対して、USER_COL_COMMENTS.COMMENTS を利用することはできますか?

    キャンセル

  • 2018/08/30 14:54

    データベースが何かやバージョンは最初に確認した方がいいです。
    >Oracleでは列のエイリアスに対して、USER_COL_COMMENTS.COMMENTS を利用することはできますか?
    できます。

    キャンセル

  • 2018/08/30 16:15 編集

    すみません、確認する必要がない。。。というか、実行可能なデータベースがあるのかと、その実行方法が聞きたかったので記述しませんでした。

    以下のようなSQLでは当然上手くいくはずもないですし、
    2013年時点でのStackOverflowですが同様の質問をされた方がいて、
    その時点での回答ではプログラム上でSQLを組み立てろということでした。
    https://stackoverflow.com/questions/15451704/output-comments-columns-instead-of-the-column-names

    どの様にしたら実現できるのですか?

    select
    CompanyId As " case when COLUMN_NAME = 'CompanyId' then COMMENTS end "
    , EmployeeId As " case when COLUMN_NAME = 'EmployeeId' then COMMENTS end "
    , EmployeeName As " case when COLUMN_NAME = 'EmployeeName' then COMMENTS end "
    from Employee
    , USER_COL_COMMENTS
    where table_name = 'Employee'

    キャンセル

  • 2018/08/31 07:43

    回答にOracleでの方法を追記しましたが、質問の内容がだいぶ変わってきたので、希望される回答とは変わっているようです。

    Oracleを使うならPL/SQLもきちんと勉強してください。
    SQLはLOOPはできませんが、PL/SQLはLOOPも使えます。最近パフォーマンス・チューニングで呼ばれると、SQLとJavaで作っていて、何千万件もあるデータを1件ずつ処理しているので時間がかかり過ぎていて、PL/SQLで作り直すと処理時間が十分の一になることもザラです。

    キャンセル

0

メジャーRDBとして、Oracle、SQL Server、DB2、MySQL、PostgreSQLなどがありますが、カラムのコメントや説明の実装はまちまちです。
標準SQL規格はありますが、20年近く前に策定されたSQL99ですらメジャーRDB間で完全互換とは言えないのが現状です。
ですから汎用的な方法はありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/30 13:57

    WITH句が使えるRDBMSなら、WITH句のサブクエリをつなげていけばいかようにも出来そうです。
    変な実装になるので書きたくはありませんが^^;

    キャンセル

  • 2018/08/30 15:14 編集

    追記②として新たにWith句を利用したSQLを作ってみましたが、
    **データ上**では期待した様な結果なのですが、
    結局列名が(c1,c2,c3)となってしまいました。
    ここから何をどうしたら良いでしょうか?

    WITH句内で一時テーブルを作成しようとするのはシステム的にNGでした
    -- 以下はNG
    with t2 as (
    create table #TEMP
    t1.c1 文字列型,
    t2.c2 文字列型,
    )

    キャンセル

  • 2018/08/30 16:20

    そこの部分は、Pivotで…
    勧めるわけではありませんが

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • SQLに関する質問
  • select した際に、列の別名に列コメントを指定できるデータベースはありますか?またはその方法 ※PL/SQL, プログラムでの動的生成は除く