SQL:展开集合

SQL:展开集合,sql,tsql,Sql,Tsql,假设我在SQL中有一个集合,如下所示: Product | Quantity A 1 B 2 我希望在单个SELECT语句中将其转换为: Product A B B 有人能给我指点T-SQL吗?这是一个如何实现的窍门吗?试试游标 DECLARE @Cursor CURSOR DECLARE @Product varchar(50) SET @Cursor

假设我在SQL中有一个集合,如下所示:

    Product | Quantity
       A         1
       B         2
我希望在单个SELECT语句中将其转换为:

    Product 
       A    
       B    
       B
有人能给我指点T-SQL吗?这是一个如何实现的窍门吗?

试试游标

DECLARE @Cursor CURSOR
DECLARE @Product varchar(50)

SET @Cursor = CURSOR FOR
SELECT Product FROM dbo._YourTable

OPEN @Cursor

FETCH NEXT FROM @Cursor INTO @Product 

WHILE @@FETCH_STATUS = 0
BEGIN

DECLARE @Count int
SET @Count = 0

DECLARE @Quantity int
SET @Quantity = SELECT Quantity FROM dbo._YourTable WHERE Product = @Product

WHILE @Count < @Quantity
BEGIN

SELECT @Product as Product
@Count = @Count + 1

END

FETCH NEXT FROM @Cursor INTO @Product
END

DEALLOCATE @Cursor

您需要一个中间数字表,或者一个表值函数(如果该选项可用于生成数字)

假设您有一个数字表,其填充方式如下:

    Number
    ------
         1
         2
       ...
    100000
或者你需要的那么大,还有

然后,您将发出以下查询:

select
    p.Product
from
    Products as p
        inner join Numbers as n on n.Number <= p.Quantity 
这将产生您想要的结果

数字表在SQL中非常有用,在他的网站上列出的书中,它和其他伟大的查询技术都有介绍。我极力推荐他们

select ProductName, Quantity from Product
产品名称数量

A 1

B 2

C4

如您所愿,这里有一个选择sql server 2005:

with result (ProductName, Q)
as
(
    select ProductName, 1 from Product where Quantity > 0
    union all
    select p1.ProductName, result.q + 1 from Product p1
    inner join result on result.ProductName = p1.ProductName
    where result.q < p1.Quantity 
)
select p2.ProductName from Product p2
    inner join result on result.ProductName = p2.ProductName
order by 1
OPTION (MAXRECURSION 0);
产品名称 A B B C C C
C

这不是取消激励;您希望根据汇总的数据重新创建行……不,这是一种简单的程序性黑客方法。我想用我在问题中所说的集合来解决这个问题。@Carl Manaster:谢谢,但我不能承担责任,我从伊兹克·本·甘的书中学到了这一点,并适当地归功于他。有几个问题:1为了避免列出数量为0的产品,请在锚定选择中添加条件,2如果数量大于100,它将不起作用,因为这是默认的递归限制,因此需要在末尾添加选项maxrecursion 0。当然,但锚点选择需要有一个实际的where子句来排除数量为零的产品,而不是从0开始:从数量>0的产品中选择产品名称,从产品中选择1