我有一张这样的表,
Id A B C D touchedwhen
1 NULL yes NULL yes 2015-02-26 14:10:01.870
1 NULL NULL no no 2015-02-26 14:10:40.370
并且需要将它们合并到这样的一行,
Id A B C D touchedwhen
1 NULL yes no no 2015-02-26 14:10:40.370.
注意:如果两行中都存在值,请按日期采用最新值..
尝试了这个问题:
select id,
max(a),
max(b),
max(c),
max(d), -- data in both rows hence take the latest
max(touchedwhen)
from
[dbo].[Table_1]
group by id;
答案 0 :(得分:0)
如果你只是在寻找每个id的最后一个值,你可以使用:
last_value(a) over(
partition by id
order by touchedwhen desc
rows between unbounded preceding and unbounded following) as a
但您正在寻找每id
not null
的最后一个值。我唯一能想到的是一个四部分连接,每个子查询计算a, b, c, d
的最新非空值:
select ids.id
, a.a
, b.b
, c.c
, d.d
, ids.tw
from (
select id
, max(touchedwhen) as tw
from YourTable
group by
id
) ids
left join
(
select row_number() over (
partition by id
order by touchedwhen desc) rn
, a
, id
from YourTable
where a is not null
) a
on a.id = ids.id
and a.rn = 1
left join
(
select row_number() over (
partition by id
order by touchedwhen desc) rn
, b
, id
from YourTable
where b is not null
) b
on b.id = ids.id
and b.rn = 1
left join
(
select row_number() over (
partition by id
order by touchedwhen desc) rn
, c
, id
from YourTable
where c is not null
) c
on c.id = ids.id
and c.rn = 1
left join
(
select row_number() over (
partition by id
order by touchedwhen desc) rn
, d
, id
from YourTable
where d is not null
) d
on d.id = ids.id
and d.rn = 1
答案 1 :(得分:0)
-- Get all latest values in one row for each primary key
WITH CTE(row_num, Id, A, B, C, D, touchedwhen) AS (
SELECT ROW_NUMBER() OVER(PARTITION BY Id ORDER BY touchedwhen DESC), Id, A, B, C, D FROM Table_1)
UPDATE CTE SET
A = (SELECT TOP 1 t.A FROM Table_1 t WHERE t.A IS NOT NULL AND t.Id = CTE.Id ORDER BY t.touchedwhen DESC),
B = (SELECT TOP 1 t.B FROM Table_1 t WHERE t.B IS NOT NULL AND t.Id = CTE.Id ORDER BY t.touchedwhen DESC),
C = (SELECT TOP 1 t.C FROM Table_1 t WHERE t.C IS NOT NULL AND t.Id = CTE.Id ORDER BY t.touchedwhen DESC),
D = (SELECT TOP 1 t.D FROM Table_1 t WHERE t.D IS NOT NULL AND t.Id = CTE.Id ORDER BY t.touchedwhen DESC)
WHERE row_num = 1
-- Delete extra rows per primary key after copying latest values to one row
WITH CTE(row_num) AS (
SELECT ROW_NUMBER() OVER(PARTITION BY Id ORDER BY touchedwhen DESC) FROM Table_1)
DELETE FROM CTE WHERE row_num > 1