有这样的表:
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来实现它,但对于大表来说这种方法很慢。我想知道是否有更快的解决方案。
答案 0 :(得分: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是一个足够大的数字来满足您的需求。这将是一次性的表格/数据创建 - 但是表格可以用于上述目的。
答案 1 :(得分: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
答案 2 :(得分: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