3

我有一张这样的桌子

 ItemsWithQuantity
 =================
 ID     Quantity
 ---------------
 x      4
 y      7

我想建立一个视图或查询,把它变成这个

ID
x
x
x
x
y
y
y
y
y
y
y

基本上不计算它们,并为每个数量获得一个唯一的行。

在 MS SQL 2005 或 2008 中动态执行此操作的最佳方法是什么

4

3 回答 3

3

最简单的方法:

SELECT iq.ID FROM ItemsWithQuantity iq
INNER JOIN master..spt_values n ON iq.Quantity > n.number AND n.type = 'p'

SQLFiddle 演示

这是将master..spt_values系统表用于数字,这是一个非常安全但仍未记录的功能。如果您不确定是否使用它,您可以创建自己的 Numbers 表来仅列出数字,或者动态创建 CTE:

WITH CTE_Numbers AS
(
    SELECT MAX(Quantity) AS Number FROM dbo.ItemsWithQuantity
    UNION ALL
    SELECT number - 1 FROM CTE_Numbers
    WHERE number >=1
)
SELECT iq.ID FROM ItemsWithQuantity iq
INNER JOIN CTE_Numbers n ON iq.Quantity > n.number
ORDER BY ID

SQLFiddle 演示

于 2013-08-02T15:35:13.217 回答
1

首先创建一个数字表 ( (ID INT NOT NULL PRIMARY KEY)),其中包含从 1 到 1m 的数字)。

然后查询变得更容易:

SELECT tab.ID
FROM ItemsWithQuantity tab
CROSS APPLY (
 SELECT ID FROM Numbers WHERE ID BETWEEN 1 AND Quantity
) x
ORDER BY tab.ID

CROSS APPLY读作“对于每个外行,加入以下行”。在我们的例子中,我们将Quantity内部行连接到每个外部行。

于 2013-08-02T15:31:04.417 回答
-1

这是一种使用循环的方法。不需要外部表或交叉表引用。

DECLARE @i INT = 1
DECLARE @counter INT
CREATE TABLE ##tempTable(
    ID INT
)
WHILE @i<=(
SELECT COUNT(*) FROM ItemsWithQuantity)
BEGIN
    SET @counter=(SELECT QuantityFROM(
    SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) RowNumber, * FROM ItemsWithQuantity) a
    WHERE RowNumber=@i)
    WHILE @counter>=0 BEGIN
        INSERT INTO ##tempTable (ID) SELECT ID FROM(
            SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) RowNumber, * FROM ItemsWithQuantity) a
            WHERE RowNumber=@i)
        SET @counter=@counter-1
    END
    SET @i=@i+1
END
SELECT * FROM ##tempTable

更新

使用临时表,您可以从一个查询中选择全部。

于 2013-08-02T15:39:40.060 回答