不确定这在纯SQL中是否可行(或值得做),但无论如何我都会问。
假设我的数据库中有一堆编号的记录(为清晰起见,还有额外的空格):
2 3 4 10 11 12 13 55 56 57 91 106 107
现在给出一个诸如“11”之类的数字我怎样才能找回“10,11,12,13”?即所有相邻的记录没有间隙(所有数字必须彼此+/- 1)。
这可能吗?如果是这样,怎么样?
答案 0 :(得分:3)
这应该可以解决问题。 @target_id
是您的目标值(在给定示例中为11)。
value-1
不存在。value+1
不存在的目标的最小值。容易!
select *
from foo t
where t.id >= ( select max(id)
from foo x
where x.id <= @target_id
and not exists ( select *
from foo x1
where x1.id = x.id - 1
)
)
and t.id <= ( select min(id)
from foo y
where y.id >= @target_id
and not exists ( select *
from foo y1
where y1.id = y.id + 1
)
)
索引您的ID /序列号列,我相信性能应该非常好。
答案 1 :(得分:1)
我什么都想不到。但如果读取速度很重要,您可以考虑添加一个代表“群集”的字段。 对于2,3和4,群集将为2.对于10,11,12和13,群集将为10,依此类推。
缺点是您必须在更新任何内容时更新群集。好的部分是算术可能非常容易。
答案 2 :(得分:1)
在不知道背景的情况下,我不能评论它是否值得(我假设没有证明不是这样),但任何事情都是可能的!我将首先使用一种方法的伪代码...
创建采用起始行ID的存储过程,其执行:
给出11的示例,第一个插入将插入#11,循环将开始,第二个插入将插入#10和#12,第三个插入将仅添加#13,第四个插入将插入0个记录,结束循环。然后你可以从ID的10,11,12,13的主表中选择。
如果程序使用不存在的数字(如#14)运行,则循环将永远不会启动,并且您将得到一个空的结果集。
你认为你能够完成这项任务还是应该写作?
答案 3 :(得分:0)
假设条目都是不同的,我们在支持窗口和CTE的DB中,
WITH t1 AS
( SELECT id, id-row_number() OVER (ORDER BY id) AS discrepancy FROM t )
SELECT id FROM t1 WHERE t1.discrepancy =
(SELECT discrepancy FROM t1 WHERE id=?);
我认为这并不像尼古拉斯的代码那么快,但它可能值得一个实验(如果你的数据库完全能够提供这个查询)。