SQL - 获取下一个和上一个X记录

时间:2017-04-09 08:01:36

标签: sql postgresql postgresql-9.1

我试图在postgresql中使用一个查询,该查询可以根据用于某些分页的起始记录ID获取上一个和下一个X个记录。只获得1个下一个或上一个并不难,但这不是我需要的。

我发现一些问题很接近但我对PostgreSQL查询知之甚少,无法进行这些类型的复杂查询。

下面的这个查询我尝试并改为工作,但似乎只带回ID的上一个和下一个项目以及所有记录。

但是我需要能够为它提供一个起点,例如在WHERE子句中提供ID,如果它们存在,则只能获得10个前一个和下一个10个记录。这可以单独在sql中完成吗?

SELECT
  m.med_id AS id,
  coalesce(
      LEAD(m.med_id) OVER (ORDER BY m.med_id DESC),
      (select med.med_id from media as med order by med.med_id desc limit 1)
  ) AS nextitemid,
  coalesce(
      LAG(m.med_id) OVER (ORDER BY m.med_id DESC),
      (select med.med_id from media as med order by med.med_id asc limit 1)
  ) AS previtemid
FROM media m
WHERE m.post_type = 1
ORDER BY m.med_id DESC LIMIT 20;

任何帮助都将受到赞赏,它可以是任何类型的SQL解决方案,可以实现这一目标。

我相信所需的输出来自100个项目的示例,给出50作为查询中提供的ID起点。

|previtemids|nextitemids|
    49           51
    48           52
    47           53
    46           54
    45           55
    44           56
    43           57
    42           58 
    41           59 
    40           60 

我已经接近但是无法在一次查询中获得它。与我的场景相近的答案比通用答案更有帮助。

2 个答案:

答案 0 :(得分:0)

with numbered as(
   select your_table.*, row_number() over(order by id) as rn from your_table 
)
SELECT previous.id, next.id FROM 
(SELECT id, row_number() over(order by id) as inner_rn FROM numbered where rn between (select rn from numbered WHERE id = 12) - 5 and (select rn from numbered WHERE id = 12) -1) previous
INNER JOIN 
(SELECT id, row_number() over(order by id) as inner_rn FROM numbered where rn between (select rn from numbered WHERE id = 12) + 1 and (select rn from numbered WHERE id = 12) + 5) next
ON previous.inner_rn = next.inner_rn

如果我理解你需要这个

这里12是starting point providing an ID,5是下一个和前一个X记录

(注意:例如,如果前一行没有10行,但下一行有10行,并且您需要使用NULL填写错过的值,则使用FULL JOIN代替INNER JOIN)< / p>

答案 1 :(得分:0)

所以这就是这样做的,我们使用它来生成0-1000之间的100个随机数字。

 <response>
<list>
<category>(noun)</category>
<synonyms>hullo|hi|howdy|how-do-you-do|greeting|salutation</synonyms>
</list>
</response>

现在我们给出了80的id,我们可以在这里找到70-90的范围。

SELECT
  trunc(random()*1000) AS x
FROM generate_series(1,100);

但我不会这样做。我会通过传递一个id和所需的行来进行分页。只允许前进。将以前的结果存储在浏览器中。