Я совсем не уверен, какова ваша цель, поэтому я не могу это прокомментировать. Однако ваша функция имеет несколько структурных ошибок, которые я могу. Итак, давайте посмотрим на них. Прежде всего, начиная с вашего подвыбора:
(
select into height avg(((p.h_feet*12)+ p.h_inches)*2.54)
from players p
)
Подвыбор может только передавать свои результаты внешнему выбору, но не может использовать предложение INTO (по крайней мере, я не могу понять, как это сделать). Но это НЕ обязательно, вы можете использовать псевдоним результата и использовать этот псевдоним во внешнем запросе. Кроме того, если бы это даже было возможно, это привело бы к ошибке времени компиляции. Необходимым форматом выбора будет «Выбрать column_list в список переменных », список переменных и список столбцов перевернуты. Наконец, Postgres требует псевдоним для подвыбора. Итак, исправляя ваши потребности:
(
select height avg(((p.h_feet*12)+ p.h_inches)*2.54) height
from players p
) p1
Переходя к внешнему запросу и заменяя подвыбор на результат, мы фактически получаем:
select rank() over(partition by height) rank
from subselect_results
where p.firstname=fn and p.lastname=ln; return coalesce(rank,0.0)
Что мы находим здесь:
- Последняя строка содержит 2 оператора, это крайне плохой процесс. Приемлемо для компилятора, но часто очень трудно найти ошибки и / или очень трудно найти исключения во время выполнения. Привыкайте к 1 оператору в строке.
- Оператору выбора в блоке кода требуется пропущенное здесь слово "в".
- Нет независимой ссылки на таблицу ни для одной таблицы. Таким образом, ЕДИНСТВЕННЫЕ доступные столбцы являются результатами подзапроса, любые ссылки на таблицы там недоступны. В этом случае единственное значение высоты. Это приводит к ошибке неопределенного столбца.
- "rank () over (разбиение по высоте)" в этой точке высота по существу постоянна. Ранжирование по константе всегда приводит к результату 1.
- Даже если вы ссылаетесь на таблицу Игроков, в которой будет указано условие where, по крайней мере, должно быть возвращено одну строку. Ранг над одной строкой всегда возвращает 1.
- Наконец, "return coalesce (rank, 0.0)". Ранг не определен как переменная. Это утверждение, что ошибка или неверные параметры вызывают ранг. Использование Postgres имени функции в качестве переменной является плохой практикой. Вам это может сойти с рук, но это также может привести к трудностям при поиске ошибок и / или исключений.
Исправление всего вышеперечисленного мы получаем функцию, которая будет фактически выполняться;
create or replace function get_rank(fn varchar, ln varchar)
returns float
language plpgsql
as $$
declare
rank_l float ;
begin
select rank() over(partition by pi.height)
into rank_l
from players p2
, (
select avg(((p.h_feet*12)+ p.h_inches)*2.54) height
from players p
) pi
where p2.firstname = fn
and p2.lastname = ln;
return rank_l;
end;
$$;
Конечно, поскольку она возвращает один ряд от игроков и ранжирует константу, это может быть заменено следующим:
create or replace function get_rank(fn varchar, ln varchar)
returns float
language plpgsql
as $$
begin
return 1.0
end;
$$;
Хотя работая с этим, кажется, что вы спрашиваете, является рангом для конкретного игрока c, основанного только на росте. Так что, возможно, вам нужно:
-- setup
create table players(id serial, firstname text, lastname text, h_feet integer, h_inches integer);
insert into players values (1,'A','B',6,3)
, (2,'C','D',6,4)
, (3,'E','F',6,9);
-- Build function
create or replace function get_rank(fn text, ln text)
returns table( firstname text
, lastname text
, height text
, rank_by_height integer
)
language sql strict
as $$
with player_ranking as
(select firstname
, lastname
, concat(trim(to_char(h_feet, '9')), '''', trim(to_char(h_inches,'00')), '"') size
, 12*h_feet + h_inches height
from players
)
select firstname, lastname, size, rnk
from (
select firstname, lastname, size, rank() over (order by height desc)::integer rnk
from player_ranking pr
) pr
where firstname = fn
and lastname = ln;
$$;
-- test
select *
from get_rank('C','D');
Я оставлю вам возможность исследовать, что делает каждая используемая функция, и разницу между sql и pgpl sql функциями. Учиться / изучать, чтобы понять, никогда не бывает в талии времени.