Функция Postgres возвращает слишком много столбцов

#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 для этой цели. Просто используйте подзапрос в своем запросе.