4

有这样一张桌子:

FromKey | ToKey | Value
------------------------
 1      |  4    | AAA 
 5      |  6    | BBB

获得以下结果的最有效方法是什么?

Key  | Value
-----------------
 1   | AAA 
 2   | AAA 
 3   | AAA 
 4   | AAA 
 5   | BBB 
 6   | BBB

我知道如何使用表函数和 CROSS APPLY 来做到这一点,但这种方法对于大表来说很慢。我想知道是否有更快的解决方案。

4

3 回答 3

4

这是一种尝试方法(完整示例,可按原样运行):

-- Dummy data
DECLARE @Data TABLE (FromKey INTEGER, ToKey INTEGER, Value VARCHAR(10))
INSERT @Data VALUES (1,4,'AAA'),(5,6,'BBB')

-- table of numbers, 1-100 for demo purposes
DECLARE @Numbers TABLE (Num INTEGER PRIMARY KEY)
INSERT @Numbers
SELECT TOP 100 ROW_NUMBER() OVER (ORDER BY object_id)
FROM sys.objects

SELECT n.Num, d.Value
FROM @Data d
    JOIN @Numbers n ON d.FromKey <= n.Num AND d.ToKey >= n.Num

我要做的是在您的数据库中创建一个物理“数字”表,并填充从 1 到 n 的数字,其中 n 是一个足够大的数字来满足您的需求。这将是一次性的表/数据创建 - 但随后该表可用于上述目的。

于 2012-04-18T08:38:03.113 回答
1
declare @t table
(
FromKey int,
ToKey int,
Value  varchar(10)
)

insert into @t values(1,4,'AAA')
insert into @t values(6,9,'BBB');
with tab as 
( 
 select FromKey , ToKey,  Value from @t 
 union all 
 select FromKey + 1, ToKey, Value 
 from tab where FromKey < ToKey 
) 
 select FromKey, Value from tab order by 1
于 2012-04-18T12:24:48.720 回答
1

只要 FromKey 和 ToKey 之间的差异小于 2047,这将起作用

declare @t table(FromKey int, ToKey int, Value varchar(3))
insert @t values(1,4, 'AAA'), (5,6, 'BBB')

select t.ToKey  - m.number [Key], t.Value 
from @t t
join
master..spt_values m ON type = 'P' AND number <= ToKey - FromKey
order by 1

这是一个递归解决方案:

declare @t table(FromKey int, ToKey int, Value varchar(3))
insert @t values(1,4, 'AAA'), (5,6, 'BBB')

;with a as
(
select FromKey [Key], ToKey,  Value from @t
union all
select [Key] + 1, ToKey, Value from a
where [Key] < ToKey
)
select [Key], Value from a
order by 1
于 2012-04-18T09:15:49.760 回答