是否可以创建动态连接?

Yve*_*man 5 postgresql pivot

如果重要的话,我正在使用 PostgreSQL。

假设这两个表:

 id | run
----+-------
  1 | run_1
  2 | run_2
  3 | run_3
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我想要以下输出:

sample | run_1 | run_2 | run_3
-------+-------+-------+-------
 samp1 | 1:09  | 0:58  | 0:55
 samp2 | 0:32  | 0:28  | 0:28
Run Code Online (Sandbox Code Playgroud)

如果我有固定数量的运行值,这很容易做到,但是是否可以创建一个动态查询,无论运行次数如何,它都会输出正确的内容?

Erw*_*ter 5

基本上它是一个交叉表查询:

但是,动态结果类型是一个问题。

...是否可以创建一个动态查询,无论运行次数如何,它都会输出正确的内容?

不。目前(包括 Postgres 9.6)不能用单个 SELECT语句。除非你知道最晚在调用时返回类型。

SQL 是一种严格类型的语言。Postgres 要求知道将从查询中返回的行类型。由用户输入以一种或另一种形式提供,或来自系统目录(注册表和类型)中的信息。从涉及的数据中推导出返回类型动态是绝对不可能的。

那为什么SELECT * FROM tbl有效呢?
因为系统目录中的每个表(视图、物化视图等)都注册了一个行类型,Postgres 通过查找它知道要返回哪些列。

无论您尝试哪种方式,您都需要两次往返数据库服务器才能使用动态结果类型进行查询:

  1. 确定结果中的列数并相应地构建SELECT语句。

  2. 执行该语句返回现在众所周知的行类型。

替代方案是:

  • 而是返回两个数组:一个包含列名,另一个包含值。
  • 返回文档类型 ( json, hstore, ...)。
  • 返回最大可能的列数并用 NULL 值填充悬空列。

我之前在 SO 上回答过类似的问题: