2016-06-14 4 views
0

У меня есть таблица в PostgreSQL, который имеет информацию, как это:Выберите наименьшее значение в столбце из набора

ID | Value | Total 
12 | 'foo' | 16 
15 | 'loo' | 1 
13 | 'too' | 11 
67 | 'roo' | 7 

Запрос я должен строить будет даваться либо один идентификатор или несколько IDS, которые запятая разделены. Необходимо вернуть только значение. Если имеется несколько идентификаторов, то возвращать только результат набора, который имеет самый низкий Total.

Это мое начало, но это не совсем то, что я после:

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; 

EDIT: Чтобы быть ясно, что я строю функцию, которая

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") 

ИЛИ

get_test_results("67, 12") 

Значения идентификатора в этом вызове не коррелируют с примерной таблицей. Результат должен ТОЛЬКО возвращать значение из самого низкого ИТОГО идентификаторов в наборе, если в функцию передано более одного идентификатора.

+1

обеспечить пример данного входа и желательно из положить – SMW

+0

'table.id = ANY (regexp_split_to_array (sample_id, '')) ; 'будет работать отлично для одного значения. Нет необходимости в выражении 'if'. Но совершенно непонятно, что вы подразумеваете под «* результатом набора, имеющего наименьшее общее количество». Пожалуйста, отредактируйте свой вопрос и добавьте ожидаемый результат на основе образца ввода –

+0

Обновлено для добавления ввода и вывода – Lithodora

ответ

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

Обратите внимание, что, как указано в комментарии, вам не нужно, чтобы проверить, если передать один или несколько значения, поскольку разделение вашего аргумента работает в обоих случаях.

Смежные вопросы