首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何选择任意行的相邻行(在sql或postgresql中)?

如何选择任意行的相邻行(在sql或postgresql中)?
EN

Stack Overflow用户
提问于 2010-09-09 06:10:56
回答 5查看 9.6K关注 0票数 21

我想根据特定的条件选择一些行,然后从该集合中选择一项,以及它之前和之后的5行。

因此,选择主键为7的行和附近的行:

select primary_key from table where primary_key > (7-5) order by primary_key limit 11;

2
3
4
5
6
-=7=-
8
9
10
11
12

但是,如果我一开始只选择某些行,我就失去了使用主键的数字方法(假设键的顺序没有任何间隙),并且需要另一种方法来在某个目标行之前和之后获得最接近的行。

这样的select的主键输出可能看起来更随机,因此不太容易进行数学定位(因为一些结果会被过滤掉,例如使用where active=1):

select primary_key from table where primary_key > (34-5) 
    order by primary_key where active=1 limit 11;

30
-=34=-
80
83
100
113
125
126
127
128
129

请注意,由于where条件示例导致的主键间隙(例如,因为有许多不活动的项),我不再获得上面最接近的5和下面的5,取而代之的是下面最接近的1和上面最接近的9。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-09-09 07:04:32

如果您使用一种编程语言运行两个查询,有很多方法可以做到这一点,但这里有一种方法可以在一个SQL查询中做到这一点:

(SELECT * FROM table WHERE id >= 34 AND active = 1 ORDER BY id ASC LIMIT 6)
UNION
(SELECT * FROM table WHERE id < 34 AND active = 1 ORDER BY id DESC LIMIT 5)
ORDER BY id ASC

这将返回上面的5行、目标行和下面的5行。

票数 27
EN

Stack Overflow用户

发布于 2010-09-09 07:53:54

这是另一种使用分析函数lead和lag的方法。如果我们可以在WHERE子句中使用解析函数,那就太好了。因此,您需要使用子查询或CTE,下面是一个适用于pagila示例数据库的示例。

WITH base AS (
    SELECT lag(customer_id, 5) OVER (ORDER BY customer_id) lag, 
      lead(customer_id, 5) OVER (ORDER BY customer_id) lead, 
      c.*
    FROM customer c
    WHERE c.active = 1
    AND c.last_name LIKE 'B%'
) 
SELECT base.* FROM base 
JOIN (
  -- Select the center row, coalesce so it still works if there aren't 
  -- 5 rows in front or behind
  SELECT COALESCE(lag, 0) AS lag, COALESCE(lead, 99999) AS lead 
  FROM base WHERE customer_id = 280
) sub ON base.customer_id BETWEEN sub.lag AND sub.lead

sgriffinusa的解决方案的问题在于,您不知道您的中心行最终会是哪个row_number。他认为应该是第三十行。

票数 7
EN

Stack Overflow用户

发布于 2014-04-16 15:08:13

对于类似的查询,我使用不带CTE的分析函数。类似于:

select ..., LEAD(gm.id) OVER (ORDER BY Cit DESC) as leadId, LEAD(gm.id, 2) OVER (ORDER BY Cit DESC) as leadId2, LAG(gm.id) OVER (ORDER BY Cit DESC) as lagId, LAG(gm.id, 2) OVER (ORDER BY Cit DESC) as lagId2 ... where id = 25912 or leadId = 25912 or leadId2 = 25912 or lagId = 25912 or lagId2 = 25912

对我来说,这样的查询比使用join的CTE更快( Scott Bailey的回答)。但当然不那么优雅

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3672283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档