2014-04-29 57 views
1
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和结束Id的值。我需要准备一个表,其中包含所有数字落在起始标识和结束标识之间需要群组和岛屿的T-SQL查询

我已经尝试了循环,但响应在现实世界中非常缓慢。

任何机构帮我查询?

这是我到目前为止已经试过......

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

当然..我已经尝试过循环,但它不会帮助我......在性能方面落后。 – vignesh

+1

请你可以举一个你预期的表格的例子吗? – sarin

+1

请用您尝试过的查询更新您的问题。 – Kermit

回答

3

假设范围id_frmid_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; 

SqlFiddle here

与ID的必要范围和聚集索引的永久表在ID上会显着提高性能。

如果范围重叠,请添加DISTINCT,并且不希望重复结果。

+0

@vignesh对于你的13位数范围,你需要将这些值建模为BIGINTs。有一些运气,你只需要一个小的动态范围(即不是从零到10^13的所有东西),你可以逐渐调整数字表以跨越所需的可能范围? – StuartLC

-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 
+1

代码只有在stackoverflow不鼓励的答案!这个地方是关于'回答问题'不只是'抛出一些代码'没有解释 – DrCopyPaste

+2

@DrCopyPaste什么?不受谁的鼓励?如果代码是答案,那很好。解释代码当然更好,但在这种情况下,它很清楚。 – Andrey

+0

@DrCopyPaste这个参数可以在明显的作业问题中部分有效(因为现成的代码会破坏学习的意义),但对于一般性问题,这是无稽之谈。 – Andrey