2015-08-03 79 views
0

我在查询中使用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条件,我的会话变量就会重置为在查询开始时初始化的值。 我只是不知道我在做什么错?据我所知,这应该很好。

+0

这是行不通的。 '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)。 –

+0

我在你的代码中看不到任何NOT ... –

+0

@Nick:当我删除我的代码的最后一行的where条件并将结果集存储到一个临时表中时,此查询完美工作。偏移值正是我想要的,我可以用临时表实现我的目标,在这个查询之后,我执行current_setting,然后它给我输出1,这是正确的,因为我已将它设置为1,但是当我使用此查询在条件和使用否定'<>'条件的情况下,current_setting给我'0'。所以,我认为逻辑上这种方法应该很好,只是我无法理解为什么当我遇到'<>'条件时出现问题 –

回答

0
select * from 
(
select 
    'result' 
    , case when 'q'='q' THEN 
      set_config('paging.count', '1',false) 
     WHEN current_setting('paging.count') = '1' THEN 
      '1' 
     ELSE 
      '0' END as offset 
) SUBQ 
where "offset" = '1' and 'q' <> 'q' 

会给你没有行并预计结果

+0

如果将条件('q'='q')更改为(uid ='q'),那么SUBQ后返回的行必须具有偏移量'1',然后结果应该有一些行在'q'之后。 –