什么时候可以替代?

时间:2018-08-16 09:23:44

标签: sql sql-server case-when

我在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语句,但无法弄清楚。有什么办法吗?

5 个答案:

答案 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;