create table #sample (rowguid int identity ,id_frm int ,id_to int)
insert into #sample values( 1,5)
insert into #sample values( 7,13)
insert into #sample values( 17,20)
在上表中,我的值为Id和Ending Id。我需要准备一个表,其中所有数字都在起始标识和结束标识之间
我已经尝试过循环,但在现实世界中反应非常慢。
任何身体帮我查询???
这是我到目前为止所尝试的......
declare @sql varchar(8000) = '
select top '+cast((select max(id_to) from #sample) as varchar(100))+' identity(int,1,1) as guidid into tally from sysobjects,syscolumns '
exec (@sql)
alter table Tally add slab varchar(10)
create clustered index idx on Tally(guidid)
create clustered index idx on #sample(id_frm asc,id_to desc)
update Tally set slab = rowguid
from #sample join Tally on guidid between id_frm and id_to
delete from Tally where slab is null
select * from Tally
此查询适用于小数
但我的实时时间表有13位数字。它通过算术溢出错误
答案 0 :(得分:3)
假设范围id_frm
和id_to
是相对较小的整数,例如< 1M,解决此问题的一种方法是创建一个包含范围内所有值并加入它的表:
WITH lotsOfNumbers AS
(
SELECT ROW_NUMBER() OVER (ORDER BY o1.object_id) AS id
FROM sys.objects o1 CROSS JOIN sys.objects o2
)
INSERT INTO #targetTable
SELECT l.ID
FROM lotsOfNumbers l
INNER JOIN #sample
ON l.ID BETWEEN #sample.id_frm AND #sample.id_to;
具有必要ID范围的永久表和ID上的聚簇索引显然会提高性能。
如果您的范围重叠,请添加DISTINCT
,并且您不希望在结果中出现重复项。
答案 1 :(得分:-2)
如果您能够在另一个表中获得全范围的可接受值,则可以在不循环的情况下使用它。下面的meathod得到最小值(1)和最大值(20),名为#range的临时表将返回介于两者之间的所有内容。
drop table #sample
drop table #range
create table #sample (id_frm int ,id_to int)
insert into #sample values( 1,5)
insert into #sample values( 7,13)
insert into #sample values( 17,20)
create table #range (id int)
insert into #range select 1
go
insert into #range select top 1 max(id)+ 1 from #range
go 100
declare @min int
declare @max int
set @min= (select min(id_frm ) from #sample )
set @max = (select max(id_to) from #sample )
select * from #range where id between @min and @max