我有一个返回表的函数.
如果运行SELECT * FROM some_function(12345)结果是:
object_id | name
----------------
12345 | "B"
Run Code Online (Sandbox Code Playgroud)
如果运行SELECT some_function(12345)结果是:
some_function
-------------
(12345,"B")
Run Code Online (Sandbox Code Playgroud)
问题是我想要原始表单(以便我可以访问单个列值),但让参数some_function()来自表中的列.我可以执行,SELECT some_function(thing_id) FROM things但这会返回:
some_function
-------------
(12345,"B")
(12346,"C")
(12347,"D")
Run Code Online (Sandbox Code Playgroud)
而我想要的回报是:
object_id | name
----------------
12345 | "B"
12346 | "C"
12347 | "D"
Run Code Online (Sandbox Code Playgroud)
那么如何"不必要"或"扩展"这样一个浓缩的行呢?
Cra*_*ger 22
在PostgreSQL 9.3或更新版本中使用隐式横向查询:
SELECT f.* FROM things t, some_function(t.thing_id) f;
Run Code Online (Sandbox Code Playgroud)
对所有新查询都喜欢这个公式.以上是标准配方.
它也可以正常使用函数,RETURNS TABLE或者RETURNS SETOF RECORD使用out-params 函数RETURNS RECORD.
它是以下的简写:
SELECT f.*
FROM things t
CROSS JOIN LATERAL some_function(t.thing_id) f;
Run Code Online (Sandbox Code Playgroud)
在此之前的版本中,会导致多种评价some_function,也没有如果工作some_function回报一组,请不要使用此:
SELECT (some_function(thing_id)).* FROM things;
Run Code Online (Sandbox Code Playgroud)
以前的版本,避免了some_function使用第二层间接的多重评估.只有在必须支持相当旧的PostgreSQL版本时才使用它.
SELECT (f).*
FROM (
SELECT some_function(thing_id) f
FROM things
) sub(f);
Run Code Online (Sandbox Code Playgroud)
建立:
CREATE FUNCTION some_function(i IN integer, x OUT integer, y OUT text, z OUT text) RETURNS record LANGUAGE plpgsql AS $$
BEGIN
RAISE NOTICE 'evaluated with %',i;
x := i;
y := i::text;
z := 'dummy';
RETURN;
END;
$$;
create table things(thing_id integer);
insert into things(thing_id) values (1),(2),(3);
Run Code Online (Sandbox Code Playgroud)
测试运行:
demo=> SELECT f.* FROM things t, some_function(t.thing_id) f;
NOTICE: evaluated with 1
NOTICE: evaluated with 2
NOTICE: evaluated with 3
x | y | z
---+---+-------
1 | 1 | dummy
2 | 2 | dummy
3 | 3 | dummy
(3 rows)
demo=> SELECT (some_function(thing_id)).* FROM things;
NOTICE: evaluated with 1
NOTICE: evaluated with 1
NOTICE: evaluated with 1
NOTICE: evaluated with 2
NOTICE: evaluated with 2
NOTICE: evaluated with 2
NOTICE: evaluated with 3
NOTICE: evaluated with 3
NOTICE: evaluated with 3
x | y | z
---+---+-------
1 | 1 | dummy
2 | 2 | dummy
3 | 3 | dummy
(3 rows)
demo=> SELECT (f).*
FROM (
SELECT some_function(thing_id) f
FROM things
) sub(f);
NOTICE: evaluated with 1
NOTICE: evaluated with 2
NOTICE: evaluated with 3
x | y | z
---+---+-------
1 | 1 | dummy
2 | 2 | dummy
3 | 3 | dummy
(3 rows)
Run Code Online (Sandbox Code Playgroud)