sql - 如何将 "condensed"PostgreSQL 行扩展到单独的列中?

标签 sql postgresql

我有一个返回表格的函数。

如果您运行 SELECT * FROM some_function(12345),结果是:

object_id | name
----------------
    12345 | "B"

如果您运行 SELECT some_function(12345),结果是:

some_function
-------------
(12345,"B")

问题是我想要原始形式(以便我可以访问各个列值),但是 some_function() 的参数来自表中的列。我可以执行 SELECT some_function(thing_id) FROM things 但这会返回:

some_function
-------------
(12345,"B")
(12346,"C")
(12347,"D")

而我想要返回的是:

object_id | name
----------------
    12345 | "B"
    12346 | "C"
    12347 | "D"

那么如何“取消嵌套”或“扩展”这样一个压缩行呢?

最佳答案

9.3及以上:横向查询

在 PostgreSQL 9.3 或更新版本中使用隐式横向查询:

SELECT f.* FROM things t, some_function(t.thing_id) f;

对于所有新查询,首选此公式。以上是标准公式

它也适用于 RETURNS TABLERETURNS SETOF RECORD 的函数以及具有 RETURNS RECORD 的输出参数的函数。

它是以下内容的简写:

SELECT f.*
FROM things t
CROSS JOIN LATERAL some_function(t.thing_id) f;

9.3 之前:通配符扩展(小心)

以前的版本,导致 some_function 的多重计算,如果 some_function 返回一个集合, 是否工作,不要使用它:

SELECT (some_function(thing_id)).* FROM things;

以前的版本,使用第二层间接避免对 some_function 进行多重计算。仅当您必须支持相当旧的 PostgreSQL 版本时才使用它。

SELECT (f).*
FROM (
  SELECT some_function(thing_id) f
  FROM things
) sub(f);

演示:

设置:

CREATE FUNCTION some_function(i IN integer, x OUT integer, y OUT text, z OUT text) RETURNS record LANGUAGE plpgsql AS $$
BEGIN
  RAISE NOTICE 'evaluated with %',i;
  x := i;
  y := i::text;
  z := 'dummy';
  RETURN;
END;
$$;

create table things(thing_id integer);
insert into things(thing_id) values (1),(2),(3);

测试运行:

demo=>     SELECT f.* FROM things t, some_function(t.thing_id) f;
NOTICE:  evaluated with 1
NOTICE:  evaluated with 2
NOTICE:  evaluated with 3
 x | y |   z   
---+---+-------
 1 | 1 | dummy
 2 | 2 | dummy
 3 | 3 | dummy
(3 rows)

demo=>     SELECT (some_function(thing_id)).* FROM things;
NOTICE:  evaluated with 1
NOTICE:  evaluated with 1
NOTICE:  evaluated with 1
NOTICE:  evaluated with 2
NOTICE:  evaluated with 2
NOTICE:  evaluated with 2
NOTICE:  evaluated with 3
NOTICE:  evaluated with 3
NOTICE:  evaluated with 3
 x | y |   z   
---+---+-------
 1 | 1 | dummy
 2 | 2 | dummy
 3 | 3 | dummy
(3 rows)

demo=>  SELECT (f).*
    FROM (
      SELECT some_function(thing_id) f
      FROM things
    ) sub(f);
NOTICE:  evaluated with 1
NOTICE:  evaluated with 2
NOTICE:  evaluated with 3
 x | y |   z   
---+---+-------
 1 | 1 | dummy
 2 | 2 | dummy
 3 | 3 | dummy
(3 rows)

关于sql - 如何将 "condensed"PostgreSQL 行扩展到单独的列中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24444008/

相关文章:

postgresql - 如何使用 pg_dump 将 postgresql 备份到远程主机?

sql - 按时间戳对行进行分组并有条件地对不同的列求和

python - 如何使用 Django 创建子类?

MySQL 连接查询,连接表中只有一条记录,按日期排序

sql - postgres 的数据文件夹的权限应该是什么

database - PostgreSQL 唯一索引和字符串大小写

postgresql - SQL : Adding Aliases to a column value

sql - 如何查询存储在数组中的 Rails ActiveRecord 数据

mysql - 用户空间点列或不在 MySQL 中以提高性能

php - 对表和元数据进行连接的 MySQL 搜索