代码之家  ›  专栏  ›  技术社区  ›  annakata

取消组合效果?

  •  7
  • annakata  · 技术社区  · 15 年前

    我有一组动态数据 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 回复  |  直到 15 年前
        1
  •  6
  •   Adriaan Stander    15 年前

    使用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
  •  7
  •   George Mastros    15 年前

    如果数据库中有一个数字表,可以使用它来帮助获得结果。在我的数据库中,有一个名为数字的表,其中有一个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
    
        3
  •  0
  •   momo    15 年前

    这个答案只不过是回G马斯特洛斯,不需要任何赞成票。我想他会感激对他已经很优秀的问题的性能提升。

    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)