2016-11-25 45 views
3

我有一個表中包含一個數字,在列中定義了一個屬性有多少車庫。現在,我需要爲所有車庫(規模,停車位數量,租賃費用等)添加更多信息,因此我必須通過插入儘可能多的記錄來創建不同表格中每個車庫的記錄。MSSQL插入n次,其中n來自一個選擇

我想什麼來完成:

SELECT ID,GarageCount FROM屬性

- 運行下面的語句GarageCount次

INSERT INTO車庫(物業ID)VALUES(Property.ID )

我需要將其運行到屬性表中的所有屬性,其中GarageCount> 0

Properties.ID是一個PK,Garages.PropertyID是一個FK。

+0

所以,如果您的查詢返回'1 ,4',你想四次插入'1'? – HoneyBadger

+0

這就是我正在尋找的。 – Daniel

回答

3

你不需要這個以「循環」的方式運行。你可以只使用一個公用表表達式生成行,與儘可能多的行每財產有在產權車庫:

with GarageRows as (
select id 
    , garagecount 
    , 0 [counter] 
from Properties 
union all 
select p.id 
    , 1 
    , gr.counter + 1 
from GarageRows gr 
    inner join Properties p on gr.id = p.id 
where gr.counter + 1 < p.garagecount) 
insert into Garages(PropertyID) 
select gr.ID 
from GarageRows gr 
where gr.garagecount > 0 

如果你只是想測試上面的CTE的結果,你可以運行下面的查詢,該查詢生成兩個屬性的行,一個包含2個車庫,另一個包含4個車庫。

declare @properties table (id int, garagecount int) 
insert @properties values (1, 2), (2, 4) 

;with GarageRows as (
select id 
    , garagecount 
    , 0 [counter] 
from @Properties 
union all 
select p.id 
    , 1 
    , gr.counter + 1 
from GarageRows gr 
    inner join @Properties p on gr.id = p.id 
where gr.counter + 1 < p.garagecount) 
select gr.ID 
from GarageRows gr 
where gr.garagecount > 0 
order by gr.ID 
+0

使用數字表重複一行非常容易 –

+0

@PanagiotisKanavos沒錯,但是如果他沒有數字表,那麼這將爲他做。 –

+0

生成一個數字表是微不足道的,並且避免了複雜的CTE –

1

您可以通過使用Numbers表避免循環和複雜的查詢。數字是一個簡單的表格,包含0以上的數字。

INSERT INTO Garages (PropertyID) 
Select Property.ID 
From Property inner join Numbers on Numbers.Number<Property.GarageCount 
where garagecount>0 

這將重複在同一行多次定義GarageCount:如果你有一個數字表連接

您的查詢變得微不足道。

Numbers表格可以用於很多場景,包括日期計算,字符串分割,識別範圍中的間隙以及將循環轉換爲無限快速的設置操作。 Aaron Bertrand寫了很多文章that explain how to generate and how to use Numbers table

阿龍貝特朗的文章顯示了一個快速的方法來生成一個索引和壓縮(它可即使在Express版本的SQL Server 2016 SP1)Numbers表格:

DECLARE @UpperBound INT = 1000000; 

;WITH cteN(Number) AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id]) - 1 
    FROM sys.all_columns AS s1 
    CROSS JOIN sys.all_columns AS s2 
) 
SELECT [Number] INTO dbo.Numbers 
FROM cteN WHERE [Number] <= @UpperBound; 

CREATE UNIQUE CLUSTERED INDEX CIX_Number ON dbo.Numbers([Number]) 
WITH 
(
    FILLFACTOR = 100,  
    DATA_COMPRESSION = ROW -- if the table is large enough to matter 
); 
+0

謝謝。這個也很好。 – Daniel