在多个结果上不存在SQL插入
本文关键字:不存在 SQL 插入 结果 | 更新日期: 2023-09-27 18:14:57
我有一个与Price表有一对多关系的Plan表。(一个计划可以有多个价格)
然而,问题是我有另一个名为"StandardPrices"的表,其中包含所有价格的名称(这样做的原因是我希望能够随时添加或删除价格)
Plan Table:
ID int primary key,
plan Name varchar(200),
...
PriceTable:
ID int primary key,
PlanId int foreign key references plan(ID)
PriceName ID foreign key standardprices(id)
StandardPrices:
ID int primary key,
PriceName varchar(200),
DefaultPrice money
所以无论何时创建一个计划,它都会自动创建一个包含StandardPrice列表中所有价格的列表(带有默认值)。
我的问题是,我需要,每当我创建一个新的StandardPrice时,它会自动检查该价格是否存在于每个计划中,如果不存在,则在该计划的价格表中创建一个条目。
我使用存储过程,并认为最好的方法是通过SQL。
创建StandardPrices时:
begin
insert into StandardPrices (PriceName, Defaultprice)
values (@priceName, @DefaultPrice)
end
begin
//list all plans.
//cross reference PriceTable to see if plan exists
//if not insert priceplan with default value
end
我有点困惑,我怎么能实现这样一个sql命令?
我觉得应该是这样的:
insert into PriceTable (PlanId, PriceName)
select PlanId, @priceName
from Plan
where not exists
(select null from PriceTable where PriceTable.PlanId = Plan.PlanId)
这样做:
if not exists
(
select *
from PriceTable
where PriceName = @priceName
)
begin
insert into PriceTable(PriceName)
values(@priceName)
end
它的作用是有条件地检查PriceName
是否已经在PriceTable
中。如果它是而不是,那么它将把新的@priceName
插入PriceTable
。我不确定你原来的帖子PlanID
的值是多少,但你应该从我上面的查询中得到这个想法。
您需要获得所有计划的列表,LEFT OUTER连接到适当的价格。如果价格记录为空,则没有适当的关联,因此添加它。
您可能需要使用游标来遍历结果并添加价格。
之类的. .
SELECT Plan.Id, Price.Id
FROM Plan LEFT OUTER JOIN Price ON Price.PlanId = Plan.Id
WHERE Price.Id = [Your New Price Id]
使用MERGE
并假设您的ID
列具有IDENTITY
属性:
MERGE INTO PriceTable
USING
(
SELECT p1.ID AS PlanId, sp1.PriceName
FROM Plan p1
CROSS JOIN StandardPrices sp1
) AS SourceTable
ON PriceTable.PlanId = SourceTable.PlanId
AND PriceTable.PriceName = SourceTable.PriceName
WHEN NOT MATCHED
THEN
INSERT ( PlanId, PriceName )
VALUES ( PlanId, PriceName ) ;
这里是一个更完整的草图,其中我将看似冗余的ID
列降级,将name
列提升为关系键,添加约束,在表之间使用一致的命名,将MONET
更改为DECIMAL
,等等:
CREATE TABLE Plans
(
plan_name VARCHAR(200) NOT NULL
UNIQUE
CHECK ( plan_name <> ' ' )
) ;
CREATE TABLE StandardPrices
(
price_name VARCHAR(200) NOT NULL
UNIQUE
CHECK ( price_name <> ' ' ),
default_price DECIMAL(19, 4) NOT NULL
CHECK ( default_price >= 0 )
) ;
CREATE TABLE Prices
(
plan_name VARCHAR(200) NOT NULL
REFERENCES Plans ( plan_name ),
price_name VARCHAR(200) NOT NULL
REFERENCES StandardPrices ( price_name ),
UNIQUE ( plan_name, price_name )
) ;
DECLARE @plan_name_new VARCHAR(200) ;
DECLARE @price_name_1 VARCHAR(200) ;
DECLARE @default_price_1 DECIMAL(19, 4) ;
DECLARE @price_name_2 VARCHAR(200) ;
DECLARE @default_price_2 DECIMAL(19, 4) ;
SET @plan_name_new = 'One'
SET @price_name_1 = 'Day'
SET @default_price_1 = 55 ;
SET @price_name_2 = 'When'
SET @default_price_2 = 99
INSERT INTO Plans ( plan_name )
VALUES ( @plan_name_new ) ;
INSERT INTO StandardPrices ( price_name, default_price )
VALUES ( @price_name_1, @default_price_1 ) ;
INSERT INTO StandardPrices ( price_name, default_price )
VALUES ( @price_name_2, @default_price_2 ) ;
MERGE INTO Prices
USING
(
SELECT p1.plan_name, sp1.price_name
FROM Plans p1
CROSS JOIN StandardPrices sp1
) AS SourceTable
ON Prices.plan_name = SourceTable.plan_name
AND Prices.price_name = SourceTable.price_name
WHEN NOT MATCHED
THEN
INSERT ( plan_name, price_name )
VALUES ( plan_name, price_name ) ;
(MySql)我建议你创建一个临时表;它是干净和可读的(我将添加不带别名,以更可读):
CREATE TEMPORARY TABLE tempTable
(
table1FK varchar(250),
table2Value varchar(250)
);
INSERT INTO tempTable(table1FK, table2Value)
VALUES ('it', '+39'),
('lt', '+370'),
('gb', '+44'),
('cn', '+86');
INSERT INTO table2(table1FK_id, table2Value)
SELECT table1.id, tempTable.prefix
FROM tempTable
inner join table1 ON table1.code = tempTable.country_code
left join table2 ON table2.country_id = table1.id
where table2.id is null;
DROP temporary TABLE tempTable;