组中每列的最后一个值,每组一行

时间:2015-01-25 05:51:03

标签: sql sql-server tsql

这应该很简单,但出于某种原因,我被卡住了。请考虑以下数据:

KEY1  KEY2  COL1    COL2    COL3
--------------------------------------
1     1     A       7       (null)
1     2     A       8       (null)
1     3     (null)  7       (null)
2     2     (null)  (null)  4
2     4     B       6       (null)
3     1     A       B       (null)

(KEY1是Id,KEY2是生成,实际上有大约30个数据列,但为了简单起见,我在这里只列出了3个。)

我希望每个Id获得一行,并且每列获取最后一个非null值。换句话说......

KEY1  COL1    COL2    COL3
----------------------------
1     A       7       (null)
2     B       6       4
3     A       B       (null)

我尝试了以下内容,但似乎除了回显我的所有行外什么也没做。

SELECT key1,
       LAST_VALUE(col1) OVER (PARTITION BY key1 ORDER BY key2 ASC) AS col1,
       LAST_VALUE(col2) OVER (PARTITION BY key1 ORDER BY key2 ASC) AS col2,
       LAST_VALUE(col3) OVER (PARTITION BY key1 ORDER BY key2 ASC) AS col3
    FROM test1

(这适用于SQL Server 2012和SQL Server Express。)

2 个答案:

答案 0 :(得分:1)

SQL Server(尚未)支持窗口函数的IGNORE NULL选项。一种方法是使用条件聚合。这需要为列智能生成序列号,以确保值" 1"为序列分配非NULL值。

这是一个应该执行此操作的查询:

select t1.key1,
       max(case when seqnum1 = 1 then col1 end) as col1,
       max(case when seqnum2 = 1 then col2 end) as col2,
       max(case when seqnum3 = 1 then col3 end) as col13
from (select t1.*,
             row_number() over (partition by key1
                                order by (case when col1 is not null then 1 else 2 end),
                                         key2 desc
                               ) as seqnum1,
             row_number() over (partition by key1
                                order by (case when col2 is not null then 1 else 2 end),
                                         key2 desc
                               ) as seqnum2,
             row_number() over (partition by key1
                                order by (case when col3 is not null then 1 else 2 end),
                                         key2 desc
                               ) as seqnum3
      from test1 t1
     ) t1
group by t1.key1

答案 1 :(得分:1)

如果我理解正确的要求,这不应该起作用吗?根据数据/列的数量,可能会非常昂贵。

select
   key1,
   (select top 1 col1 from test1 t2 where t.key1 = t2.key1 and col1 is not null order by key2 desc) as col1,
   (select top 1 col2 from test1 t2 where t.key1 = t2.key1 and col2 is not null order by key2 desc) as col2,
   (select top 1 col3 from test1 t2 where t.key1 = t2.key1 and col3 is not null order by key2 desc) as col3
from 
   (select distinct key1 from test1) t