Dum*_*tru 3 sql postgresql composite left-join lateral-join
如何在一个函数中包含一个返回复合类型的函数SELECT?
我有复合类型:
CREATE TYPE public.dm_nameid AS (
id public.dm_int,
name public.dm_str
);
Run Code Online (Sandbox Code Playgroud)
此外,我有一个函数返回此类型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
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
PS我读过这篇文章.
PPS我不想要以下方法:
SELECT
p.id, p.data, p.name,
(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
Run Code Online (Sandbox Code Playgroud)
SELECT p.id, p.name, p.data, f.*
FROM tb_projects p
LEFT JOIN LATERAL fn_getlinkedproject(p.id) f(linked_id, lined_name) ON TRUE;
Run Code Online (Sandbox Code Playgroud)
呼叫:
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
Run Code Online (Sandbox Code Playgroud)
更好地使用LATERAL第9.3页的连接
SELECT p.id AS p_id, p.data AS p_data, p.name AS p_name, (fn_getlinkedproject(p.id)).*
FROM tb_projects p;
Run Code Online (Sandbox Code Playgroud)
结果:
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
Run Code Online (Sandbox Code Playgroud)
如果要重命名结果列,则必须:
SELECT p.id, p.data, p.name
,(fn_getlinkedproject(p.id)).id AS linked_id
,(fn_getlinkedproject(p.id)).name AS linked_name
FROM tb_projects p;
Run Code Online (Sandbox Code Playgroud)
或者使用子查询来避免函数被调用两次(如果函数很昂贵):
SELECT p.id, p.data, p.name
, (p.x).id AS linked_id, (p.x).name AS linked_name
FROM (SELECT *, fn_getlinkedproject(id) AS x FROM tb_projects) p;
Run Code Online (Sandbox Code Playgroud)
或者,在第9.3页中:
CREATE TYPE dm_nameid AS (
id int
, name text); -- types simplified for demo
CREATE TABLE tb_projects(
id int
, 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) -- avoiding CaMeL-case for demo
RETURNS dm_nameid LANGUAGE sql AS
'SELECT id, name FROM tb_projects WHERE id = ($1 % 3) + 1';
Run Code Online (Sandbox Code Playgroud)
结果:
SELECT p.id, p.name, p.data, f.*
FROM tb_projects p
LEFT JOIN LATERAL fn_getlinkedproject(p.id) f(linked_id, lined_name) ON TRUE;
Run Code Online (Sandbox Code Playgroud)
使用PostgreSQL 8.4 - 9.3进行测试.可能也适用于8.2或8.3(未经测试).
注意圆括号的位置!这些都很重要.
阅读有关复合类型的手册.
| 归档时间: |
|
| 查看次数: |
3836 次 |
| 最近记录: |