如何在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.