我有两个表:products
和products_discounts
。如果某个产品被指定为“前 10 名”产品,并且在 中缺少定义的折扣products_discounts
,我想products_discounts
为每个缺少的记录插入一条记录。插入的值将由product_id
INSERT INTO中的和另外两个硬编码值组成。
产品
id、product_id、名称、top_ten
Products_Discounts
id、product_id、discount_amount、discount_description
以下是我计划如何手动执行此操作,但由于我将每年重复此过程几次,因此我想看看这是否可以通过几行 SQL 完成。
(1) 获取符合我的条件的产品列表。
SELECT p.product_id, pd.discount_amount FROM products AS p
LEFT OUTER JOIN products_discounts AS pd
ON p.product_id = pd.product_Id
WHERE p.top_ten = 1
AND pd.product_id IS NULL
Run Code Online (Sandbox Code Playgroud)
(2) 使用文本编辑器构建每个单独的 INSERT INTO 语句。我会使用步骤 1 的输出来获取product_id
s 但其他两个值将保持不变(硬编码)。
INSERT INTO products_discounts (product_id, discount_amount, discount_description)
VALUES ('<product_id goes here>', 10, 'Top 10 Product')
Run Code Online (Sandbox Code Playgroud)
这些步骤可以组合成几行SQL吗?
这可能会做你想做的:
SELECT 'INSERT INTO products_discounts (product_id, discount_amount, discount_description)
VALUES (''' + CONVERT(varchar(30), p.product_id) + ''', 10, ''Top 10 Product'')
'
FROM products AS p
LEFT OUTER JOIN products_discounts AS pd
ON p.product_id = pd.product_Id
WHERE p.top_ten = 1
AND pd.product_id IS NULL;
Run Code Online (Sandbox Code Playgroud)
它为所有前 10 名没有产品折扣的产品生成报表。无需在 Excel 中执行此操作。只需将结果复制并粘贴到 SSMS 中的新查询窗口中并运行它。话虽如此,您可能希望自动化此过程,这可以使用这样的游标来完成:
DECLARE @cmd nvarchar(max);
DECLARE cur CURSOR LOCAL FORWARD_ONLY STATIC
FOR
SELECT 'INSERT INTO products_discounts (product_id, discount_amount, discount_description)
VALUES (''' + CONVERT(varchar(30), p.product_id) + ''', 10, ''Top 10 Product'')
'
FROM products AS p
LEFT OUTER JOIN products_discounts AS pd
ON p.product_id = pd.product_Id
WHERE p.top_ten = 1
AND pd.product_id IS NULL;
OPEN cur;
FETCH NEXT FROM cur INTO @cmd;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC sys.sp_executesql @cmd;
FETCH NEXT FROM cur INTO @cmd;
END
CLOSE cur;
DEALLOCATE cur;
Run Code Online (Sandbox Code Playgroud)
或者在基于集合的方法中,像这样:
DECLARE @cmd nvarchar(max);
SELECT @cmd = CASE WHEN @cmd IS NULL THEN N'' ELSE @cmd END
+ N'INSERT INTO products_discounts (product_id, discount_amount, discount_description)
VALUES (''' + CONVERT(varchar(30), p.product_id) + ''', 10, ''Top 10 Product'')
'
FROM products AS p
LEFT OUTER JOIN products_discounts AS pd
ON p.product_id = pd.product_Id
WHERE p.top_ten = 1
AND pd.product_id IS NULL;
EXEC sys.sp_executesql @cmd;
Run Code Online (Sandbox Code Playgroud)
我很难理解为什么你不能这样做:
INSERT dbo.products_discounts (product_id, discount_amount, discount_description)
SELECT p.product_id, 10, 'Top 10 Product'
FROM dbo.products AS p
LEFT OUTER JOIN dbo.products_discounts AS pd
ON p.product_id = pd.product_Id
WHERE p.top_ten = 1
AND pd.product_id IS NULL;
Run Code Online (Sandbox Code Playgroud)
实际上,更直观地说,恕我直言:
INSERT dbo.products_discounts (product_id, discount_amount, discount_description)
SELECT p.product_id, 10, 'Top 10 Product'
FROM dbo.products AS p
WHERE p.top_ten = 1
AND NOT EXISTS
(
SELECT 1 FROM dbo.products_discounts AS pd
WHERE p.product_id = pd.product_Id
);
Run Code Online (Sandbox Code Playgroud)
是不是因为折扣金额(10
)因产品而异?与我们分享您使用哪些规则来确定折扣是否应该不是10
。如果您不能定义这些,那么 SQL Server 也不能(动态 SQL、循环或游标等也不能)。
归档时间: |
|
查看次数: |
1035 次 |
最近记录: |