web-dev-qa-db-ja.com

動的結合を作成することは可能ですか?

必要に応じて、PostgreSQLを使用しています。

次の2つのテーブルを想定します。

 id | run
----+-------
  1 | run_1
  2 | run_2
  3 | run_3

そして

sample | elapsed |  run
-------+---------+-------
 samp1 | 1:09    | run_1
 samp2 | 0:32    | run_1
 samp1 | 0:58    | run_2
 samp2 | 0:28    | run_2
 samp1 | 0:55    | run_3
 samp2 | 0:28    | run_3

次の出力が必要です。

sample | run_1 | run_2 | run_3
-------+-------+-------+-------
 samp1 | 1:09  | 0:58  | 0:55
 samp2 | 0:32  | 0:28  | 0:28

これは、実行値の数が決まっている場合に十分簡単ですが、実行数に関係なく正しいものを出力する動的クエリを作成することは可能ですか?

4
Yves Dorfsman

基本的にはクロス集計クエリです:

ただし、動的な結果タイプは問題です。

...実行の回数に関係なく正しいものを出力する動的クエリを作成することは可能ですか?

いいえ。現在(Postgres 9.6を含む)はsingleSELECTステートメントでは使用できません。遅くとも、呼び出し時の戻り値の型を知っている場合を除きます。

SQLは厳密に型指定された言語です。 Postgresはクエリから返される行タイプを知ることを要求します。いずれかの形式でユーザーが入力するか、システムカタログ(登録されているテーブルとタイプ)の情報から提供されます。関連するdataから戻り値の型を動的に推測することは、厳密には不可能です。

では、なぜSELECT * FROM tbl仕事?
システムカタログのすべてのテーブル(ビュー、マテリアライズドビューなど)に登録された行タイプがあり、Postgresはそれを検索することでどの列を返すかを認識しているためです。

どちらの方法を試しても、動的な結果タイプのクエリでは、データベースサーバーへの2つのラウンドトリップが必要です。

  1. 結果の列数を決定し、それに応じてSELECTステートメントを作成します。

  2. 現在よく知られている行タイプを返す上記のステートメントを実行します。

代替案は次のとおりです。

  • 代わりに2つの配列を返します。1つは列名を含み、もう1つは値を含みます。
  • ドキュメントタイプ(jsonhstore、...)を返します。
  • 可能な最大列数を返し、ダングリング列をNULL値で埋めます。

私はSOの前に同様の質問に答えました:

4