我在PostgreSQL中有一个表,其中包含以下信息:
ID | Value | Total
12 | 'foo' | 16
15 | 'loo' | 1
13 | 'too' | 11
67 | 'roo' | 7
我必须构建的查询将被赋予一个逗号分隔的单个ID或多个IDS。只需要返回Value。如果有多个ID,则仅返回具有最低总计的集合的结果。
这是我的开始,但它并不完全是我所追求的:
IF(position(',' in sample_id)>0) THEN
RETURN QUERY SELECT value FROM table WHERE table.id = ANY(regexp_split_to_array(sample_id,','));
ELSE
RETURN QUERY SELECT value FROM table WHERE table.id = sample_id;
END IF;
编辑:要明确我正在构建一个
的功能CREATE OR REPLACE FUNCTION public.get_test_results(IN sample_id text)
RETURNS TABLE(test_result text) AS
$BODY$
BEGIN
IF(position(',' in sample_id)>0) THEN
RETURN QUERY SELECT value FROM table WHERE table.id = ANY(regexp_split_to_array(sample_id,','));
ELSE
RETURN QUERY SELECT value FROM table WHERE table.id = sample_id;
END IF;
END;
$BODY$
使用:
get_test_results("342949283940829308")
OR
get_test_results("67, 12")
此调用中的ID值与示例表无关。如果有多个ID传递给函数,结果应仅返回集合中ID的最低TOTAL值。
答案 0 :(得分:1)
您可以在嵌套选择中获取min(table.total)
。
我不使用PostgreSQL,但如果你的例子有效,你应该写:
RETURN QUERY SELECT table.value FROM table WHERE table.id = ANY(regexp_split_to_array(sample_id,',')) and table.total in (
SELECT min(tbl.total) FROM table tbl WHERE tbl.id = ANY(regexp_split_to_array(sample_id,','))
);
请注意,正如评论中所述,您不需要检查是否传递了一个或多个值,因为在两种情况下都可以分割您的参数。
答案 1 :(得分:1)
只需使用限制条款:
select value
from the_table
where id = ANY(regexp_split_to_array(sample_id,',')::int[])
order by total
limit 1;
请注意,您还需要将regexp_split_to_array
的结果转换为整数数组(::int[]
),否则您无法使用any()
将其与整数列进行比较。
你也不需要PL / pgSQL。一个简单的SQL函数可以:
CREATE OR REPLACE FUNCTION public.get_test_results(IN sample_id text)
RETURNS TABLE(test_result text) AS
$BODY$
select value
from the_table
where id = ANY(regexp_split_to_array(sample_id,',')::int[])
order by total
limit 1;
$BODY$
language sql;
请注意,如果有多个行具有相同的最小值,则上述行只会返回一行。
如果您需要所有这些行,可以使用窗口函数:
select value
from (
select value, dense_rank() over (order by total) as rnk
from the_table
where id = ANY(regexp_split_to_array(sample_id,',')::int[])
) t
where rnk = 1