PostgreSQL:从返回复合类型的函数中选择

如何在SELECT中包含一个返回复合类型的函数?
我有复合类型:

CREATE TYPE "public"."dm_nameid" AS (
  "id" "public"."dm_int","name" "public"."dm_str"
);

此外,我有一个函数返回此类型fn_GetLinkedProject(整数).
我需要做这样的事情:

SELECT 
    p.id,p.data,p.name,pl.id linked_id,pl.name linked_name
FROM tb_projects p
   left join "fn_GetLinkedProject"(p.id) pl

我怎样才能做到这一点?

附:
我看过this篇文章.

P.P.S.
我不想要以下方法:

SELECT
 p.id,(select pl1.id from "fn_GetLinkedProject"(p.id) pl1 ) linked_id,(select pl2.name from "fn_GetLinkedProject"(p.id) pl2 ) linked_name
FROM tb_projects p

解决方法

试试这个演示

CREATE TYPE dm_nameid AS (
  id int,name text); -- simplified for demo

CREATE TABLE tb_projects(
  id   integer,data text,name text);

INSERT INTO tb_projects VALUES
  (1,'data_1','name_1'),(2,'data_2','name_2'),(3,'data_3','name_3');

CREATE function fn_getlinkedproject(integer)
  RETURNS dm_nameid AS
$func$
   SELECT id,name FROM tb_projects
   WHERE  id = ($1 % 3) + 1;
$func$LANGUAGE sql;

呼叫:

SELECT p.id AS p_id,p.data AS p_data,p.name AS p_name,(fn_getlinkedproject(p.id)).*
FROM   tb_projects p;

最好在第9.3页使用LATERAL加入

SELECT p.id AS p_id,f.*
FROM   tb_projects p
LEFT   JOIN LATERAL fn_getlinkedproject(p.id) f ON TRUE;

结果:

p_id | p_data | p_name | id |  name
------+--------+--------+----+--------
    1 | data_1 | name_1 |  2 | name_2
    2 | data_2 | name_2 |  3 | name_3
    3 | data_3 | name_3 |  1 | name_1

如果要重命名结果列,则必须:

SELECT p.id,(fn_getlinkedproject(p.id)).id   AS linked_id,(fn_getlinkedproject(p.id)).name AS linked_name
FROM   tb_projects p;

或者使用子查询来避免函数被调用两次(如果函数很昂贵):

SELECT p.id,(p.x).id AS linked_id,(p.x).name AS linked_name
FROM  (SELECT *,fn_getlinkedproject(id) AS x FROM tb_projects) p;

或者,在第9.3页:

SELECT p.id AS p_id,f.id AS linked_id,f.name AS linked_name
FROM   tb_projects p
LEFT   JOIN LATERAL fn_getlinkedproject(p.id) f ON TRUE;

结果:

id |  data  |  name  | linked_id | linked_name
----+--------+--------+-----------+-------------
  1 | data_1 | name_1 |         2 | name_2
  2 | data_2 | name_2 |         3 | name_3
  3 | data_3 | name_3 |         1 | name_1

使用PostgreSQL 8.4 – 9.3进行测试.可能也适用于8.2或8.3(未经测试).
注意圆括号的位置!这些都很重要.
阅读manual about composite types.

相关文章

文章浏览阅读601次。Oracle的数据导入导出是一项基本的技能,...
文章浏览阅读553次。开头还是介绍一下群,如果感兴趣polardb...
文章浏览阅读3.5k次,点赞3次,收藏7次。折腾了两个小时多才...
文章浏览阅读2.7k次。JSON 代表 JavaScript Object Notation...
文章浏览阅读2.9k次,点赞2次,收藏6次。navicat 连接postgr...
文章浏览阅读1.4k次。postgre进阶sql,包含分组排序、JSON解...