2013-08-02 16 views

回答

3

最簡單的方法:

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

SQLFiddle DEMO

這是使用master..spt_values系統表中的數字,這是一個非常安全的,但仍無證功能。如果你不確定如何使用它,你可以創建自己的數字表將只列出的數字,或動態創建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 DEMO

1

首先創建一個數字表((ID INT NOT NULL PRIMARY KEY))的最佳方式。

然後查詢變得更加容易:

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內部行連接到每個外部行。

-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 [email protected]) 
    WHILE @counter>=0 BEGIN 
     INSERT INTO ##tempTable (ID) SELECT ID FROM(
      SELECT ROW_NUMBER() OVER (ORDER BY ID DESC) RowNumber, * FROM ItemsWithQuantity) a 
      WHERE [email protected]) 
     SET @[email protected] 
    END 
    SET @[email protected]+1 
END 
SELECT * FROM ##tempTable 

UPDATE

使用臨時表,你可以從一個查詢中選擇所有。

+0

解釋downvote? –

+0

不是downvoter,但是與其他兩個答案相比,這看起來非常不合適和沒有效率。我很好奇看到所有三個比較的執行計劃和表現。 – LittleBobbyTables

+0

@LittleBobbyTables兩個其他解決方案都需要創建一個包含一串數字(即「1到1m的數字」)的表格。這是我的解決方案提出的不必要的。 –

相關問題