#sql #database #postgresql
Вопрос:
Я пытаюсь создать функцию
CREATE OR REPLACE FUNCTION get_post(integer) RETURNS SETOF post AS $
select *, lag(id) over (order by id) as prev_id, lead(id) over (order by id) as next_id
from post
where id=$1 limit 1;
$ language SQL;
но это дает мне такую ошибку, как.
Query 1 ERROR: ERROR: return type mismatch in function declared to return post
DETAIL: Final statement returns too many columns.
Я знаю, что ошибка связана с prev_id
и next_id
в выборе. Но не уверен, как я могу включить next_id
и prev_id
по возвращении.
вы можете использовать этот sqlfiddle: http://sqlfiddle.com/#!9/6e6dd6/4
ИЗМЕНИТЬ: это дает мне ту же ошибку после преобразования запроса с помощью подзапроса.
CREATE OR REPLACE FUNCTION get_post(integer) RETURNS SETOF post AS $
select
p.*,
(select id from post where id>p.id ORDER BY id asc LIMIT 1) as next_id,
(select id from post where id<p.id ORDER BY id desc LIMIT 1) as prev_id
from post p
where id=$1 limit 1;
$ language SQL;
Комментарии:
1. Даже если бы это сработало, это не сделало бы того, чего вы хотите.
WHERE
Предложение фильтруется передLEAD()
иLAG()
, таким образом, эти результаты будутNULL
. Вам нужно использовать подзапрос или CTE. Ну, я действительно могу придумать способ обойти это, но это довольно дорого.2. @GordonLinoff, да, вы правы, он возвращает значение NULL, используя предложение where. есть какие-нибудь обходные пути ?
3. . . Я уже объяснял в ответе на ваш предыдущий вопрос, что вы просто используете подзапрос (или CTE, если хотите).
4. @GordonLinoff, да, используя подзапрос, я также получаю ту же ошибку. смотрите мою правку.
5. . . Я не рекомендую UDF для этой цели. Просто используйте подзапрос в своем запросе.