2016-11-25 2 views
3

У меня есть таблица, которая содержит число в столбце, определяющем количество гаражей, которое имеет свойство. Теперь мне нужно добавить дополнительную информацию обо всех гаражах (размер, количество парковочных мест, арендную плату и т. Д.), Поэтому я должен создавать записи для каждого гаража в другой таблице, вставляя столько записей, сколько есть гаражей.MSSQL вставляет n раз, где n получается из выбора

То, что я хотел бы выполнить:

ВЫБЕРИТЕ ID, GarageCount из свойств

- запустить следующий раз заявление GarageCount

INSERT INTO Гаражи (PropertyID) VALUES (Property.ID)

Мне нужно запустить это ко всем свойствам в таблице свойств, где GarageCount> 0

Свойства.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 

Если вы просто хотите проверить результат КТРА выше, вы можете запустите следующий запрос, который генерирует строки для двух свойств: один с двумя гаражами и один с 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

Это намного проще повторить строку, используя таблицу Numbers –

+0

@PanagiotisKanavos Правда, но если у него нет таблицы чисел, это сделает это для него. –

+0

Создание таблицы чисел тривиально и позволяет избежать сложных CTE –

1

Вы можете избежать циклов и сложных запросов, используя таблицу Numbers. A Numbers - это простая таблица, которая содержит числа от 0 вверх.

Ваш запрос становится тривиальным, если вы присоединитесь с таблицей Numbers:

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

Это будет повторять ту же строку, как много раз, как это определено GarageCount.

Таблица Numbers может использоваться во многих сценариях, включая расчеты даты, разбиение строк, выявление пробелов в диапазонах и преобразование циклов в бесконечно более быстрые операции. Аарон Бертран написал много статей that explain how to generate and how to use Numbers table.

статья

Аарон Бертрана демонстрирует быстрый способ создания таблицы Numbers с индексом и сжатия (который доступен даже в экспресс-выпусков с SQL Server 2016 SP1):

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

Смежные вопросы