我遇到一种情况,我需要在其中一个表中创建一个表的数据副本,并在其中使用不同范围的外键。例如:
--------------------------------------------------------------
|TYPES |ITEMS |SUBITEMS |
|--------------|----------------------|----------------------|
| ID | VALUE | ID | VALUE | TYPEID | ID | VALUE | ITEMID |
|----|---------|----|--------|--------|----|--------|--------|
| 1 | TYPE1 | 1 | ITEMA | 1 | 1 | SUB1 | 1 |
| 2 | TYPE2 | 2 | ITEMB | 1 | 2 | SUB2 | 2 |
| | | 3 | ITEMC | 1 | 3 | SUB3 | 3 |
| | | 4 | ITEMD | 2 | | | |
| | | 5 | ITEME | 2 | | | |
| | | 6 | ITEMF | 2 | | | |
--------------------------------------------------------------
在这里,我必须从SUBITEMS复制并插入回去,但其中TYPEID为2的ITEMID会导致以下示例:
--------------------------------------------------------------
|TYPES |ITEMS |SUBITEMS |
|--------------|----------------------|----------------------|
| ID | VALUE | ID | VALUE | TYPEID | ID | VALUE | ITEMID |
|----|---------|----|--------|--------|----|--------|--------|
| 1 | TYPE1 | 1 | ITEMA | 1 | 1 | SUB1 | 1 |
| 2 | TYPE2 | 2 | ITEMB | 1 | 2 | SUB2 | 2 |
| | | 3 | ITEMC | 1 | 3 | SUB3 | 3 |
| | | 4 | ITEMD | 2 | 4 | SUB1 | 4 |
| | | 5 | ITEME | 2 | 5 | SUB2 | 5 |
| | | 6 | ITEMF | 2 | 6 | SUB3 | 6 |
--------------------------------------------------------------
编辑2:如果在任何一个表中有不同的行数(4个项目同时有3个子项目或3个项目同时有4个子项目),则仅应考虑那些足以满足两个表之间1:1关系的行(3个结果因为这是两者中最少的一个),如以下示例所示。
--------------------------------------------------------------
|TYPES |ITEMS |SUBITEMS |
|--------------|----------------------|----------------------|
| ID | VALUE | ID | VALUE | TYPEID | ID | VALUE | ITEMID |
|----|---------|----|--------|--------|----|--------|--------|
| 1 | TYPE1 | 1 | ITEMA | 1 | 1 | SUB1 | 1 |
| 2 | TYPE2 | 2 | ITEMB | 1 | 2 | SUB2 | 2 |
| | | 3 | ITEMC | 1 | 3 | SUB3 | 3 |
| | | 4 | ITEMD | 2 | 4 | SUB1 | 4 |
| | | 5 | ITEME | 2 | 5 | SUB2 | 5 |
| | | 6 | ITEMF | 2 | 6 | SUB3 | 6 |
| | | 7 | ITEMG | 2 | | | |
--------------------------------------------------------------
当然,实际数据并不是那么简单,并且具有许多其他类型和项n个子项,并且所需的ID会丢失一些序列,例如10001、10008、40042等,还有许多其他列都定义了要复制哪些数据以及哪些ID需要扔给他们。只是如何将获得的每个数据行都以1:1映射到获得的每个ID(假设这两个数据集好像在合并之前在自己的临时表中一样)。以下是到目前为止我能做的一个例子:
CREATE TABLE #SubItemsTemp (Value VARCHAR(100))
CREATE TABLE #ItemIDsTemp (TypeID INT)
INSERT INTO #SubItemsTemp (Value)
SELECT
SI.Value
FROM
SubItems SI
JOIN Items IT ON SI.ItemID = IT.ID
WHERE
IT.TypeID = 1
INSERT INTO #ItemIDsTemp(Value)
SELECT IT.ID
FROM Items IT
WHERE IT.TypeID = 2
--What next?
编辑1:忘记提及实际的问题行...如何将它们一起插入SUBITEMS表中,以使第二个示例实现?
脚注:这是对具有多个联接才能到达“ TYPE”的实际查询的极大简化
最佳答案
试试这个查询。查询假定ID
表中的SUBITEMS
列是标识,并且仅适用于TypeId的1和2
declare @TYPES table(ID int, VALUE varchar(100))
declare @ITEMS table(ID int, VALUE varchar(100), TYPEID int)
declare @SUBITEMS table(ID int identity(1,1), VALUE varchar(100), ITEMID int)
insert into @TYPES values (1, 'TYPE1'), (2, 'TYPE2')
insert into @ITEMS values (1, 'ITEMA', 1), (2, 'ITEMB', 1), (3, 'ITEMC', 1), (4, 'ITEMD', 2), (5, 'ITEME', 2), (6, 'ITEMF', 2), (7, 'ITEMG', 2)
insert into @SUBITEMS values ('SUB1', 1), ('SUB2', 2), ('SUB3', 3)
; with cte_1 as (
select
s.VALUE, rn = row_number() over (order by i.ID)
from
@ITEMS i
join @SUBITEMS s on s.ITEMID = i.ID
where
i.TYPEID = 1
)
, cte_2 as (
select
ID, rn = row_number() over (order by ID)
from
@ITEMS
where
TYPEID = 2
)
insert into @SUBITEMS
select
a.VALUE, b.ID
from
cte_1 a
join cte_2 b on a.rn = b.rn
select * from @SUBITEMS
输出量
ID Value ItemId
------------------
1 SUB1 1
2 SUB2 2
3 SUB3 3
4 SUB1 4
5 SUB2 5
6 SUB3 6
关于sql - SQL用一系列值更新表列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48921012/