gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 11:39:20 26 4
gpt4 key购买 nike

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

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

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

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文章。

我不想要以下方法:

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

最佳答案

Postgres 9.3 或更高版本

使用 LATERAL加入!

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;

结果:

 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

参见:

Postgres 9.2 或更早版本

劣势有几个原因。附加列别名并不那么简单。而是重命名其他冲突的名称:

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

结果:

 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, p.data, p.name
,(fn_getlinkedproject(p.id)).id AS linked_id
,(fn_getlinkedproject(p.id)).name AS linked_name
FROM tb_projects p;

两种旧解决方案都解决了重复调用函数的相同(糟糕)查询计划。

为避免这种情况,请使用子查询:

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;

注意基本括号的位置。
阅读 manual about composite types .

演示

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';

db<> fiddle here

关于sql - 从返回复合类型的 PostgreSQL 函数中选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4284762/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com