我在查询中使用Postgres会话变量来处理分页。postgresql会话变量在使用非条件时被重置
我有一个表消息(id,uid,body,user_id,posted_date)。 我选择属于给定用户的消息,然后通过posting_date进行排序。现在我必须在消息列表中的给定uid之后返回消息。为此,我使用会话变量,
select set_config('paging.count', '0',false)
SELECT *
FROM
(SELECT
m2.uid, m2.id,
case when uid = 'XYZ' THEN
set_config('paging.count', '1',false)
WHEN current_setting('paging.count') = '1' THEN
'1'
ELSE
'0' END as offset
FROM
(SELECT m1.*,mu.* FROM schema_1.message m1
WHERE m1.user_id = 1 AND m1.id IN (4078,4076,4080,4031,4055,4056,4057,3596,4193,4467,4389,4285,4338,)
ORDER BY posted_date) m2 ) m
WHERE m.offset = '1' and m.uid <> 'XYZ'
在这里,我初始化会话变量设置为1时,在查询中选择了给定的UID,该UID后,所有的消息都会有偏差为1,因此,我将得到所有给定消息之后的消息通过添加一个偏移条件。但是,只有当我不使用最后的NOT条件时,此查询才能正常工作。但只要我应用NOT条件,我的会话变量就会重置为在查询开始时初始化的值。 我只是不知道我在做什么错?据我所知,这应该很好。
这是行不通的。 'SELECT'语句不是'for'循环。 Postgres可以并且将重新排列您的查询,因为它认为合适。特别是,因为'current_setting'是['STABLE'](http://www.postgresql.org/docs/9.4/static/xfunc-volatility.html),所以每个查询只能评估一次。你应该尝试[另一种方法](https://wiki.postgresql.org/images/3/35/Pagination_Done_the_PostgreSQL_Way.pdf)。 –
我在你的代码中看不到任何NOT ... –
@Nick:当我删除我的代码的最后一行的where条件并将结果集存储到一个临时表中时,此查询完美工作。偏移值正是我想要的,我可以用临时表实现我的目标,在这个查询之后,我执行current_setting,然后它给我输出1,这是正确的,因为我已将它设置为1,但是当我使用此查询在条件和使用否定'<>'条件的情况下,current_setting给我'0'。所以,我认为逻辑上这种方法应该很好,只是我无法理解为什么当我遇到'<>'条件时出现问题 –