分组效应?

时间:2010-08-12 15:27:38

标签: sql sql-server tsql

我有以下形式的动态数据集 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的解决方案,但我正在寻找超效率,所以我想知道是否有一种基于语句,非程序性的方式来获得这种“取消组合”的效果?

感觉就像一个不透明,但我的大脑现在无法到达那里。

3 个答案:

答案 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,UNPIVOTCTE,您可以尝试类似

的内容
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)