从select中插入每一行后执行函数

时间:2018-05-01 19:56:16

标签: sql-server

我有两张桌子。第一个表有数据

Table_1
===================

ID | Name | Status       | Code
-------------------------------------
1  | John | Manager      | A
2  | Don  | Manager      | A
2  | Don  | Supervisor   | B
3  | Jim  | Manager      | A
3  | Jim  | Supervisor   | B
3  | Jim  | Employee     | C

现在我有另一个表格,我想移动这些数据,所以我使用了select语句中的Insert,但是在Table_2表格中,我希望每个Name都具有所有三种状态(经理,主管,员工)

如果table_1中的名称已经具有全部3状态和代码,那么它应该从select中插入而不进行任何更改,但是如果它只有1个状态,那么table_2应该插入两个具有相同id的虚拟名称AND如果名称有两个条目然后只输入1个具有相同ID的虚拟名称。

这是我真正想要的Table_2:

 Table_2
 ===================

 ID | Name | Status       | Code
 -------------------------------------
 1  | John | Manager      | A
 1  | Dum1 | Supervisor   | B
 1  | Dum2 | Employee     | C
 2  | Don  | Manager      | A
 2  | Don  | Supervisor   | B
 2  | Dum2 | Employee     | C
 3  | Jim  | Manager      | A
 3  | Jim  | Supervisor   | B
 3  | Jim  | Employee     | C

我在select语句中使用Insert,但只是将数据格式table_1复制到table_2

2 个答案:

答案 0 :(得分:2)

您可以使用表构造函数和cross apply

declare @table1 table (ID int, Name varchar(64), status varchar(64), Code char(1))
insert into @table1
values
(1,'John','Manager','A'),
(2,'Don','Manager','A'),
(2,'Don','Supervisor','B'),
(3,'Jim','Manager','A'),
(3,'Jim','Supervisor','B'),
(3,'Jim','Employee','C')



declare @table2 table (ID int, Name varchar(64), status varchar(64), Code char(1))

insert into @table2 (ID, Name, Status, Code)
select distinct
    ID
    ,Name
    ,x.Status
    ,Code = case 
                when x.Status = 'Manager' then 'A'
                when x.Status = 'Supervisor' then 'B'
                when x.Status = 'Employee' then 'C'
            end
from @table1
cross apply (values('Manager'),('Supervisor'),('Employee')) x(Status)
order by
    ID
    ,x.Status


update t2
    set t2.Name = 'Dummy_' + case 
                                when t2.Status =  'Manager' then '1'
                                when t2.Status =  'Supervisor' then '2'
                                when t2.Status =  'Employee' then '3'
                            end
from
    @table2 t2
left join
    @table1 t1 on t1.ID = t2.ID and t1.Code = t2.Code
where
    t1.ID is null



select *
from @table2
order by ID, Code

答案 1 :(得分:2)

到目前为止,最大的问题是您的数据未正常化。这会带来很多挑战。可能有一种更简单的方法来实现这一目标,但这就是我想出的。第一步是使用几个ctes来使您的数据标准化,以便您可以轻松地加入它。从那里开始,一个简单的ROW_NUMBER将为您提供Dummy_1等,它将针对每个ID值重新启动,并且无论ID在缺失数据中的哪个位置,都将按顺序排列。

使用来自scsimon的精细样本数据和表格,我把它放在一起。

declare @table1 table (ID int, Name varchar(64), status varchar(64), Code char(1))
insert into @table1
values
(1,'John','Manager','A'),
(2,'Don','Manager','A'),
(2,'Don','Supervisor','B'),
(3,'Jim','Manager','A'),
(3,'Jim','Supervisor','B'),
(3,'Jim','Employee','C')
;

with Codes as
(
    select distinct Code
        , Status
    from @table1
)
, IDs as
(
    select distinct ID
    from @table1
)
select i.ID
    , Name = case when t.Name is null then 'Dummy_' + convert(varchar(10), row_number() over(partition by i.ID, t.Name order by c.Code)) else t.Name end
    , c.Status
    , c.Code
from Codes c
cross join IDs i
left join @table1 t on t.code = c.Code and t.ID = i.ID
order by i.ID
    , c.Code