如何根据 sql 服务器中其他列的值插入新行?
How to insert new rows based on values in other columns in sql server?
我有如下数据集:
Id A14_Comment A15_Comment A16_Comment
1 Comment1 null null
2 Comment2 Comment3 Comment4
3 null Comment5 Comment6
4 null null Comment7
我需要做的是得到下面的输出:
Id A14_Comment A15_Comment A16_Comment Code
1 Comment1 null null A14
2 Comment2 Comment3 Comment4 A14
2 Comment2 Comment3 Comment4 A15
2 Comment2 Comment3 Comment4 A16
3 null Comment5 Comment6 A15
3 null Comment5 Comment6 A16
4 null null Comment7 A16
可以看出,我的目的是通过标记代码来添加一个Code
列和复制行。下面的查询给了我多少次我需要为每行添加不同代码的行,但无法找到一种有效的方法来完成剩下的工作。
select Id, (
select count(*)
from (values (T.A14_Comment), (T.A15_Comment), (T.A16_Comment)) as v(col)
where v.col is not null and v.col <> ''
) from #Comments as T
如有任何帮助,我们将不胜感激。
下面的查询将给出预期的结果:-
select * From (
select *,'A14' Code from #Comments where A14_Comment is not null union all
select *,'A15' Code from #Comments where A15_Comment is not null union all
select *,'A16' Code from #Comments where A16_Comment is not null) as xData order by ID,Code
ID A14_Comment A15_Comment A16_Comment Code
1 Comment1 NULL NULL A14
2 Comment2 Comment3 Comment4 A14
2 Comment2 Comment3 Comment4 A15
2 Comment2 Comment3 Comment4 A16
3 NULL Comment5 Comment6 A15
3 NULL Comment5 Comment6 A16
4 NULL NULL Comment7 A16
将 table 加入 CTE:
with
codes as (
select 'A14' code
union all
select 'A15'
union all
select 'A16'
),
idcodes as (
select comments.id, codes.code
from comments cross join codes
)
select *
from comments c inner join idcodes i
on
c.id = i.id
and (
c.A14_Comment is not null and i.code = 'A14'
or
c.A15_Comment is not null and i.code = 'A15'
or
c.A16_Comment is not null and i.code = 'A16'
)
参见demo。
结果:
> Id | A14_Comment | A15_Comment | A16_Comment | code
> -: | :---------- | :---------- | :---------- | :---
> 1 | Comment1 | null | null | A14
> 2 | Comment2 | Comment3 | Comment4 | A14
> 2 | Comment2 | Comment3 | Comment4 | A15
> 2 | Comment2 | Comment3 | Comment4 | A16
> 3 | null | Comment5 | Comment6 | A15
> 3 | null | Comment5 | Comment6 | A16
> 4 | null | null | Comment7 | A16
我会使用 apply
:
select c.*, c.code
from #Comments c cross apply
(select c.code
from (values (c.A14_Comment, 'A14'), (c.A15_Comment, 'A15'), (c.A16_Comment, 'A16')
) v(col, code)
where col is not null
) c;
其实子查询是没有必要的。您可能会发现这更简单:
select c.*, v.code
from #Comments c cross apply
(values (c.A14_Comment, 'A14'), (c.A15_Comment, 'A15'), (c.A16_Comment, 'A16')
) v(col, code)
where v.col is not null
我有如下数据集:
Id A14_Comment A15_Comment A16_Comment
1 Comment1 null null
2 Comment2 Comment3 Comment4
3 null Comment5 Comment6
4 null null Comment7
我需要做的是得到下面的输出:
Id A14_Comment A15_Comment A16_Comment Code
1 Comment1 null null A14
2 Comment2 Comment3 Comment4 A14
2 Comment2 Comment3 Comment4 A15
2 Comment2 Comment3 Comment4 A16
3 null Comment5 Comment6 A15
3 null Comment5 Comment6 A16
4 null null Comment7 A16
可以看出,我的目的是通过标记代码来添加一个Code
列和复制行。下面的查询给了我多少次我需要为每行添加不同代码的行,但无法找到一种有效的方法来完成剩下的工作。
select Id, (
select count(*)
from (values (T.A14_Comment), (T.A15_Comment), (T.A16_Comment)) as v(col)
where v.col is not null and v.col <> ''
) from #Comments as T
如有任何帮助,我们将不胜感激。
下面的查询将给出预期的结果:-
select * From (
select *,'A14' Code from #Comments where A14_Comment is not null union all
select *,'A15' Code from #Comments where A15_Comment is not null union all
select *,'A16' Code from #Comments where A16_Comment is not null) as xData order by ID,Code
ID A14_Comment A15_Comment A16_Comment Code
1 Comment1 NULL NULL A14
2 Comment2 Comment3 Comment4 A14
2 Comment2 Comment3 Comment4 A15
2 Comment2 Comment3 Comment4 A16
3 NULL Comment5 Comment6 A15
3 NULL Comment5 Comment6 A16
4 NULL NULL Comment7 A16
将 table 加入 CTE:
with
codes as (
select 'A14' code
union all
select 'A15'
union all
select 'A16'
),
idcodes as (
select comments.id, codes.code
from comments cross join codes
)
select *
from comments c inner join idcodes i
on
c.id = i.id
and (
c.A14_Comment is not null and i.code = 'A14'
or
c.A15_Comment is not null and i.code = 'A15'
or
c.A16_Comment is not null and i.code = 'A16'
)
参见demo。
结果:
> Id | A14_Comment | A15_Comment | A16_Comment | code
> -: | :---------- | :---------- | :---------- | :---
> 1 | Comment1 | null | null | A14
> 2 | Comment2 | Comment3 | Comment4 | A14
> 2 | Comment2 | Comment3 | Comment4 | A15
> 2 | Comment2 | Comment3 | Comment4 | A16
> 3 | null | Comment5 | Comment6 | A15
> 3 | null | Comment5 | Comment6 | A16
> 4 | null | null | Comment7 | A16
我会使用 apply
:
select c.*, c.code
from #Comments c cross apply
(select c.code
from (values (c.A14_Comment, 'A14'), (c.A15_Comment, 'A15'), (c.A16_Comment, 'A16')
) v(col, code)
where col is not null
) c;
其实子查询是没有必要的。您可能会发现这更简单:
select c.*, v.code
from #Comments c cross apply
(values (c.A14_Comment, 'A14'), (c.A15_Comment, 'A15'), (c.A16_Comment, 'A16')
) v(col, code)
where v.col is not null