Как добавить НОВЫЕ значения в одну таблицу вместе со значениями в другой таблице в третью таблицу?

У меня есть три стола. Мы назовем их "Данные", "Период" и "Тип". Данные содержат запись для каждой записи в типе и каждой записи в периоде, поэтому длина данных равна длине периода, умноженной на длину типа.

Type:
TypeID(primary key int)
TypeName(vchar)

Period:
PeriodID(primary key int)
PeriodName(varchar)

Data:
DataID(primary key int)
PeriodID(relational int)
TypeID(relational int)
Value(int)

Время от времени в период будут добавляться новые значения, но тип должен оставаться неизменным в обозримом будущем. То, что я хочу сделать, это вставить новые записи в данные для каждого нового периода (PeriodIDs, которые данные еще не содержат), по одной для каждого TypeID. Таким образом, если имеется 5 новых записей периода и 6 записей типа, в данных должно быть 30 новых записей. Я не уверен, как сделать это кратко с SQL. Производительность не является проблемой, поскольку как Period, так и Type являются достаточно маленькими таблицами.

3 ответа

Решение

Декартово произведение и подзапрос должны делать то, что вы хотите:

insert into Data (PeriodID, TypeID)
select PeriodID, TypeID
from Period, Type
where PeriodID not in (select PeriodID from Data)

Обратите внимание, что предполагается, что ваш столбец DataID будет сгенерирован автоматически, а столбец Value будет иметь значение null (поэтому должен иметь значение null) Возможно, вам придется изменить SQL, если это не так.

Сразу после вставки в таблицу Period вы можете использовать оператор:

insert into Data(PeriodID,TypeID, Value) 
select scope_identity(), TypeId, @DefaultValue From Type;

или вы можете использовать триггер, если невозможно добавить после вставки каждого нового значения в таблицу Period в транзакции:

insert into Data(PeriodID,TypeID, Value) 
select i.PeriodID, t.TypeId, @DefaultValue from inserted i cross join Type t

Обратите внимание, что предполагается, что ваш столбец DataID генерируется автоматически, а столбец Value будет заполнен значением переменной @DefaultValue, которое вы должны объявить перед оператором, например так:

declare @DefaultValue int = 0;

Похоже, вы ищете, чтобы получить перекрестный продукт

INSERT INTO Data
SELECT P.PeriodID, T.TypeID, 'some value' AS Value
FROM Period P
CROSS JOIN Type T

Быстрый пример результатов

DECLARE @Period TABLE (
    PeriodID int
    )

DECLARE @Type TABLE (
    TypeID int
    )

insert into @Period
VALUES
    (1),(2),(3)
insert into @Type
VALUES
    (4),(5),(6)

SELECT P.PeriodID, T.TypeID, 'some value' AS Value
FROM @Period P
CROSS JOIN @Type T

Результаты

1   4   some value
2   4   some value
3   4   some value
1   5   some value
2   5   some value
3   5   some value
1   6   some value
2   6   some value
3   6   some value
Другие вопросы по тегам