SQL - 与varchar一起使用SUM

时间:2017-05-26 08:28:43

标签: sql sql-server group-by

有一个(奇怪的)表格看起来像这样

ID    Version   Value1    Value2    Value3
1     1         Shaft     
1     2                   steel     xy
2     1                   Knife     somethins
2     3         Super

想要合并,需要有这个结果,使用最高版本的Value,其中包含内容:

ID    Value1    Value2    Value3
1     Shaft     steel     xy
2     Super     Knife     somethin

据我所知,使用Max(版本)的组会带来最高版本行的NULL值。

像SUM这样的东西?

4 个答案:

答案 0 :(得分:1)

第二次尝试......可能有更短更好的解决方案,但它应该有效:

with
v1 as 
(
select w1.id, w1.value1 from weird w1
where w1.value1 is not null
and w1.version=(select max(w11.version) from weird w11 where w11.id=w1.id and w11.value1 is not null) 
),
v2 as 
(
select w2.id, w2.value2 from weird w2
where w2.value2 is not null
and w2.version=(select max(w22.version) from weird w22 where w22.id=w2.id and w22.value2 is not null) 
),
v3 as 
(
select w3.id, w3.value3 from weird w3
where w3.value3 is not null
and w3.version=(select max(w33.version) from weird w33 where w33.id=w3.id and w33.value3 is not null) 
)
select v1.id, v1.value1, v2.value2, v3.value3
from v1, v2, v3
where v1.id=v2.id and v1.id=v3.id;

答案 1 :(得分:1)

我们可以创造性地使用UNPIVOT and PIVOT来构建您想要的数据:

declare @t table (ID int not null, Version int not null, Value1 varchar(20) null,
                  Value2 varchar(20) null, Value3 varchar(20) null)
insert into @t(ID,Version,Value1,Value2,Value3) values
(1,1,'Shaft',null,null),
(1,2,null,'steel','xy'),
(2,1,null,'Knife','somethins'),
(2,3,'Super',null,null)

;With Numberable as (
    select *,ROW_NUMBER() OVER (PARTITION BY ID,Val ORDER BY Version desc) rn
    from @t t
    unpivot (tdata for Val in (Value1,Value2,Value3)) u
), Selected as (
    select ID,tdata,Val
    from Numberable where rn = 1
)
select
    *
from Selected s
pivot (MAX(tdata) for Val in (Value1,Value2,Value3)) u

UNPIVOT会自动删除NULLROW_NUMBER()标识了我们要保留的值。 Selected CTE会隐藏我们不再需要的列,以便PIVOT创建我们想要的最终结果:

ID          Value1               Value2               Value3
----------- -------------------- -------------------- --------------------
1           Shaft                steel                xy
2           Super                Knife                somethins

(我在枢轴中使用MAX,但这只是为了满足优化器。因为我们只为每个ID选择了一行,{{ 1}}组合,我们知道最多只会选择一个值出现在由枢轴形成的网格中的最终位置。

以上确实假设ValValue1Value2都具有相同或至少兼容的数据类型。

答案 2 :(得分:0)

您可以使用row_number对值进行排名。以下查询首先构建此类排名。 rn1按版本的降序按idvalue1 is null / not null构建。因此,根据ID,我们得到#1表示最后一个空值和最后一个填充值。稍后我们使用rn1 = 1来获取两者中的最大值,这是最后一个填充值。 rn2 / value2rn3 / value3也是如此。

select 
  id,
  min(case when rn1 = 1 then value1 end) as value1,
  min(case when rn2 = 1 then value2 end) as value2,
  min(case when rn3 = 1 then value3 end) as value3
from
(
  select 
    id, value1, value2, value3,
    row_number() over (partition by id, case when value1 is null then 0 else 1 end order by version desc) as rn1,
    row_number() over (partition by id, case when value2 is null then 0 else 1 end order by version desc) as rn2,
    row_number() over (partition by id, case when value3 is null then 0 else 1 end order by version desc) as rn3
  from mytable
) ranked
group by id
order by id;

答案 3 :(得分:-1)

CASE WHEN用于SELECT max(version),其中值为not nullnot blank,然后joined使用原始表格。您可以在查询

下方提供的链接中查看它

使用此查询。

Select distinct a.*, b.value1, c.value2, d.value3
from
(
Select id, max(case when (value1 is not null and value1 <> ' ') then version else 0 end) as ver1,
max(case when (value2 is not null and value2 <> ' ') then version else 0 end) as ver2,
max(case when (value3 is not null and value3 <> ' ') then version else 0 end) as ver3
from
your_table
group by id
) a
inner join
your_table b,
your_table c,
your_table d
where (a.ver1=b.version and a.id=b.id)
and (a.ver2=c.version and a.id=c.id)
and (a.ver3=d.version and a.id=d.id)

在此link

中查看此处的操作