SQL更新包含值序列

时间:2018-02-22 06:31:30

标签: sql sql-server

我遇到这种情况,我需要在其中一个列中创建一个表的数据副本,其中一个表中包含不同范围的外键。例如:

--------------------------------------------------------------
|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      |    |        |        |
--------------------------------------------------------------

当然,实际数据并不简单,并且有许多其他类型和项目的子项目,并且所需的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"

1 个答案:

答案 0 :(得分:1)

尝试此查询。查询假定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