如何从PostgreSQL 9.4的匿名行类型中获取第一个字段?

18
=# select row(0, 1) ;
  row
-------
 (0,1)
(1 row)

如何在同一查询中获取0?我想到了下面这种工作方式,但有没有更简单的方法?

=# select json_agg(row(0, 1))->0->'f1' ;
 ?column?
----------
 0
(1 row)

使用类数组语法 [0] 没有成功。

谢谢!


3
row 构造函数创建一个 匿名记录。你可以使用 row_to_json 函数来滥用它。因为它们不是数组,所以您不能使用数组运算符对它们进行索引。字段的类型可能不同。实际上,PostgreSQL 对匿名记录的支持很有限,通常不建议依赖它们。 - Craig Ringer
4个回答

2

您的行类型是匿名的,因此无法轻松访问其元素。您可以创建一个TYPE,然后将您的匿名行转换为该类型,并访问在类型中定义的元素:

CREATE TYPE my_row AS (
  x integer,
  y integer
);

SELECT (row(0,1)::my_row).x;

正如Craig Ringer在您的问题中所评论的那样,如果可能的话,您应该避免产生匿名行,并在数据模型和查询中输入所使用的任何数据类型。


1
这可能是一个正确的答案,对我来说完美地工作。如果有另一种方法可以避免声明新数据类型的负担(例如使用匿名数据类型),那就很好了。谢谢! - Victor

2
如果您只想从任何行中获取第一个元素,请将该行转换为JSON并选择f1...
SELECT row_to_json(row(0,1))->'f1'

如果你总是有两个整数或者一个固定的结构,你可以创建一个临时表(或类型)和一个选择第一列的函数。

CREATE TABLE tmptable(f1 int, f2 int);
CREATE FUNCTION gettmpf1(tmptable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;

SELECT gettmpf1(ROW(0,1)); 

Resources:

https://www.postgresql.org/docs/9.2/static/functions-json.html https://www.postgresql.org/docs/9.2/static/sql-expressions.html


4
请注意,row_to_json的结果是无类型的。很遗憾,PostgreSQL没有匿名记录的访问器! - Chris

1
json解决方案非常优雅。仅供娱乐,这是一种使用正则表达式的解决方案(更丑陋):
WITH r AS (SELECT row('quotes, "commas",
and a line break".',null,null,'"fourth,field"')::text AS r)
--WITH r AS (SELECT row('',null,null,'')::text AS r)
--WITH r AS (SELECT row(0,1)::text AS r)
SELECT CASE WHEN r.r ~ '^\("",' THEN ''
            WHEN r.r ~ '^\("' THEN regexp_replace(regexp_replace(regexp_replace(right(r.r, -2), '""', '\"', 'g'), '([^\\])",.*', '\1'), '\\"', '"', 'g')
            ELSE (regexp_matches(right(r.r, -1), '^[^,]*'))[1] END
FROM r

当将行转换为文本时,PostgreSQL使用带引号的CSV格式。我找不到任何导入带引号的CSV到数组的工具,因此上述内容是通过大多数正则表达式进行粗略文本操作。也许有人会发现这很有用!

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接