如何将行扩展为多行结果集?

时间:2012-11-14 19:06:50

标签: sql sql-server sql-server-2008

我有一个表,我试图根据第二列值将每行分成一行或多行。像这样:

table (id, pcs):
ABC   3
DEF   1
GHJ   4

query result (id, pcs_num):
ABC   1
ABC   2
ABC   3
DEF   1
GHJ   1
GHJ   2
GHJ   3
GHJ   4

我在SQL Server 2008中将其写为sproc。我最好的解决方案是使用游标并将[pcs]行数添加到表中每行的临时表中。似乎必须有一个比我更缺失的简单解决方案。感谢。

3 个答案:

答案 0 :(得分:6)

您可以使用递归CTE:

;WITH CTE AS
(
    SELECT *
    FROM YourTable
    UNION ALL 
    SELECT id, pcs-1
    FROM CTE
    WHERE pcs-1 >= 1
)
SELECT *
FROM CTE
ORDER BY id, pcs
OPTION(MAXRECURSION 0)

Here is a demo让你尝试。

答案 1 :(得分:0)

这是我的方法。使用Tally Table非常容易(一个表只有一个值为1的列 - > X)。不需要递归,这比较大的表要快得多。

请注意,我们只制作了100行的Tally Table,您可以根据自己的需要随意扩展。如果你太疯狂了,你可能需要在sys.sysobjects中另一个交叉连接来容纳。真正的查询位于底部,因为您可以看到它非常简单。

SELECT TOP 100
        IDENTITY( INT,1,1 ) AS N 
 INTO #Tally
FROM    sys.sysobjects sc1 ,

        sys.sysobjects  sc2

CREATE TABLE #Test
(
    Id char(3),
    pcs int
)

INSERT INTO #Test
SELECT 'ABC', 3 UNION ALL
SELECT 'DEF', 1 UNION ALL
SELECT 'GHJ', 4

SELECT #Test.Id, #Tally.N FROM #Tally
    JOIN #Test ON #Tally.N <= #Test.pcs
    ORDER BY #Test.Id

答案 2 :(得分:0)

SELECT
  id
 ,pcs_num
FROM MyTable
CROSS APPLY (
  SELECT TOP (pcs)
    ROW_NUMBER() OVER(ORDER BY (SELECT 1)) pcs_num
  FROM master.dbo.spt_values
) t