我有一个物料表作为源表,如下所示:
CREATE TABLE dbo.MATERIAL (
ID int IDENTITY(1,1) NOT NULL,
CATEGORY_ID int NOT NULL,
SECTION_ID int NOT NULL,
STATUS_ID int NOT NULL
)
我也有一个Order表作为目标表,如下所示:
CREATE TABLE dbo.ORDER (
ID int IDENTITY(1,1) NOT NULL,
MATERIAL_ID int NOT NULL
)
我将ome数据发送到SQL Server到存储过程并创建了以下临时表
DECLARE @temptable TABLE (
CATEGORY_ID int NOT NULL,
SECTION_ID int NOT NULL,
STATUS_ID int NOT NULL,
COUNT int NOT NULL
)
并填写了如下数据:
CATEGORY_ID SECTION_ID STATUS_ID COUNT
----------- ---------- --------- -----
3 8 1 10
8 2 2 11
4 6 1 8
我想要的是匹配MATERIAL表中的COUNT个材料,这些材料匹配同一行的给定CATEGORY_ID,SECTION_ID和STATUS_ID三元组;然后将这些记录的ID插入目标表ORDER。
我该如何完成这项任务?
问候。
答案 0 :(得分:1)
现在丢掉了一堆以前的工作,我认为我理解要求。
这是一个有效的SQL FIDDLE:
这会生成一个名为GENROWS的数据集,其中包含的行数等于temptable中最大计数的计数。它通过使用递归公用表表达式(CTE)为temptable中的每个最大计数计数生成1行来实现此目的。 然后,它使用此数据集连接到temptable和material,以生成需要按顺序插入材料的次数。
我不喜欢使用保留字,所以我将order
调整为morder
,我建议调整列count
,否则你将被困在[]中。不时。
注意:这假设材料表中不存在重复项(具有相同category_ID,Section_Id和Status_ID的记录)。如果有;然后这可能会或可能不会像预期的那样。
最后,现在我已经更好地理解了在你不肯定之后你会发现什么,与使用游标相比,你会看到很多性能提升。因为必须以某种方式生成行。这仍然可以更快一些,因为我们生成集合并一次插入所有而不是单独插入。但是产生存储和检索产生的数据集可能会抵消这种增益。只有测试才能证明。
WITH
GenRows (RowNumber, Val) AS (
-- Anchor member definition
SELECT 1 AS RowNumber, (Select max(count) val from temptable) val
UNION ALL
-- Recursive member definition
SELECT a.RowNumber + 1 AS RowNumber, a.val
FROM GenRows a
WHERE a.RowNumber < a.val
)
Insert into morder (Material_ID)
SELECT A.ID
FROM material A
INNER JOIN temptable B
on A.Category_ID = B.Category_ID
and A.Section_Id = B.Section_Id
and A.Status_Id = B.Status_ID
INNER JOIN GenRows
on GenRows.RowNumber <= b.[count]
答案 1 :(得分:1)
我想我找到了解决方案。我应该使用CURSOR。以下代码可以解决这个问题:
DECLARE @MATERIAL_ID int
DECLARE @CATEGORY_ID int
DECLARE @SECTION_ID int
DECLARE @STATUS_ID int
DECLARE @COUNT int
DECLARE cur CURSOR LOCAL FOR
SELECT
CATEGORY_ID,
SECTION_ID,
STATUS_ID,
COUNT
FROM
@temptable
OPEN cur
FETCH NEXT FROM cur INTO @CATEGORY_ID, @SECTION_ID, @STATUS_ID, @COUNT
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO
dbo.ORDER
(MATERIAL_ID)
SELECT
TOP (@COUNT) ID
FROM
dbo.MATERIAL AS m
WHERE
m.CATEGORY_ID = @CATEGORY_ID
AND m.SECTION_ID = @SECTION_ID
AND m.STATUS_ID = @STATUS_ID
FETCH NEXT FROM cur INTO @CATEGORY_ID, @SECTION_ID, @STATUS_ID, @COUNT
END
CLOSE cur
DEALLOCATE cur