我有以下形式的动态数据集 X :
----------------------------------
x.id | x.allocated | x.unallocated
----------------------------------
foo | 2 | 0
bar | 1 | 2
----------------------------------
我需要得到 Y 的结果(顺序不重要):
----------------------------------
y.id | y.state
----------------------------------
foo | allocated
foo | allocated
bar | allocated
bar | unallocated
bar | unallocated
----------------------------------
我有一个基于UTF的解决方案,但我正在寻找超效率,所以我想知道是否有一种基于语句,非程序性的方式来获得这种“取消组合”的效果?
感觉就像一个不透明,但我的大脑现在无法到达那里。
答案 0 :(得分:7)
如果数据库中有数字表,则可以使用它来帮助获得结果。在我的数据库中,我有一个名为Numbers的表,其中包含Num列。
Declare @Temp Table(id VarChar(10), Allocated Int, UnAllocated Int)
Insert Into @Temp Values('foo', 2, 0)
Insert Into @Temp Values('bar',1, 2)
Select T.id,'Allocated'
From @Temp T
Inner Join Numbers
On T.Allocated >= Numbers.Num
Union All
Select T.id,'Unallocated'
From @Temp T
Inner Join Numbers
On T.unAllocated >= Numbers.Num
答案 1 :(得分:6)
使用Sql Server 2005,UNPIVOT和CTE,您可以尝试类似
的内容DECLARE @Table TABLE(
id VARCHAR(20),
allocated INT,
unallocated INT
)
INSERT INTO @Table SELECT 'foo', 2, 0
INSERT INTO @Table SELECT 'bar', 1, 2
;WITH vals AS (
SELECT *
FROM
(
SELECT id,
allocated,
unallocated
FROM @Table
) p
UNPIVOT (Cnt FOR Action IN (allocated, unallocated)) unpvt
WHERE Cnt > 0
)
, Recurs AS (
SELECT id,
Action,
Cnt - 1 Cnt
FROM vals
UNION ALL
SELECT id,
Action,
Cnt - 1 Cnt
FROM Recurs
WHERE Cnt > 0
)
SELECT id,
Action
FROM Recurs
ORDER BY id, action
答案 2 :(得分:0)
这个答案只是回到G Mastros并且不需要任何赞成。我认为他会欣赏他已经出众的查询的性能提升。
SELECT
T.id,
CASE X.Which WHEN 1 THEN 'Allocated' ELSE 'Unallocated' END
FROM
@Temp T
INNER JOIN Numbers N
On N.Num <= CASE X.Which WHEN 1 THEN T.Allocated ELSE T.Unallocated END
CROSS JOIN (SELECT 1 UNION ALL SELECT 2) X (Which)