我在SQL中有一张表,结果看起来像这样:
Number | Name | Name 2
1 | John | Derek
1 | John | NULL
2 | Jane | Louise
2 | Jane | NULL
3 | Michael | Mark
3 | Michael | NULL
4 | Sara | Paul
4 | Sara | NULL
我想说一种方法,如果Number = 1,则在新列Name 3中返回Name 2,这样结果将如下所示:
Number | Name | Name 2 | Name 3
1 | John | Derek | Derek
1 | John | NULL | Derek
2 | Jane | Louise | Louise
2 | Jane | NULL | Louise
3 | Michael | Mark | Mark
3 | Michael | NULL | Mark
4 | Sara | Paul | Paul
4 | Sara | NULL | Paul
问题在于我无法说出Number = 1是否在Name 3中返回Name 2,因为我的表有> 100,000条记录。我需要它来自动执行。类似于“如果Number相同,则在Name 3中返回Name 2”。我尝试使用CASE语句,但无法弄清楚。有什么办法吗?
答案 0 :(得分:3)
根据经验,这似乎可行:
SELECT
Number, Name, [Name 2],
MAX([Name 2]) OVER (PARTITION BY Number) [Name 3]
FROM yourTable;
如果我正确解释了您的要求,这里的想法是,您要报告 all 记录的第二名称的非NULL
值作为第三名称值。
答案 1 :(得分:1)
解决方案3,分组依据
with maxi as(
SELECT Number, max(Name2) name3
FROM @sample
group by number, name
)
SELECT f1.*, f2.name3
FROM @sample f1 inner join maxi f2 on f1.number=f2.number
答案 2 :(得分:0)
您可以尝试以下操作:
解决方案1,具有行号
declare @sample table (Number integer, Name varchar(50), Name2 varchar(50))
insert into @sample
select 1 , 'John' , 'Derek' union all
select 1 , 'John' , NULL union all
select 2 , 'Jane' , 'Louise' union all
select 2 , 'Jane' , NULL union all
select 3 , 'Michael' , 'Mark' union all
select 3 , 'Michael' , NULL union all
select 4 , 'Sara' , 'Paul' union all
select 4 , 'Sara' , NULL ;
with tmp as (
select *, row_number() over(partition by number order by number) rang
from @sample
)
select f1.Number, f1.Name, f1.Name2, f2.Name2 as Name3
from tmp f1 inner join tmp f2 on f1.Number=f2.Number and f2.rang=1
答案 3 :(得分:0)
解决方案4,交叉应用
SELECT *
FROM @sample f1 cross apply
(
select top 1 f2.Name2 as Name3 from @sample f2
where f2.number=f1.number and f2.Name2 is not null
) f3
答案 4 :(得分:-1)
解决方案2,带有滞后(如果您的sql Server版本具有滞后功能)
SELECT
Number, Name, Name2,
isnull(Name2, lag(Name2) OVER (PARTITION BY Number order by number)) Name3
FROM @sample;