我有一些结构不平衡的电子表格
ID Date Val Date Val Date Val
1 2000/01/01 2 2000/12/31 1
2 1999/01/28 6 2001/02/01 5 2001/12/31 6
....
我想将其重新排列为以下内容
ID Date Val
1 2000/01/01 2
1 2000/12/31 1
2 1999/01/28 6
2 2001/02/01 5
2 2001/12/31 6
....
样本数据:
create table tmp
(
id smallint not null,
date1 Date,
val1 smallint,
date2 date,
val2 smallint,
date3 date,
val3 smallint
);
insert into tmp(id, date1, val1, date2, val2) values (1, '2001-01-01',5,'2001-12-31',6);
insert into tmp(id, date1, val1, date2, val2, date3, val3) values (2, '1999-02-01',3,'2000-12-31',2, '2001-05-01',3);
select * from tmp
1 2001-01-01 5 2001-12-31 6 NULL NULL
2 1999-02-01 3 2000-12-31 2 2001-05-01 3
但是以下代码将返回
select c.* from tmp cross apply
(
select id, date1, val1 from tmp where date1 is not null
union all
select id, date2, val2 from tmp where date2 is not null
union all
select id, date3, val3 from tmp where date3 is not null
)
as c
1 2001-01-01 5
1 2001-01-01 5
2 1999-02-01 3
2 1999-02-01 3
1 2001-12-31 6
1 2001-12-31 6
2 2000-12-31 2
2 2000-12-31 2
2 2001-05-01 3
2 2001-05-01 3
答案 0 :(得分:1)
从SQL Server 2005开始,您可以将函数/子查询应用于源数据集中的每一行。
SELECT
normalised.*
FROM
yourTable AS tmp
CROSS APPLY
(
SELECT tmp.id, tmp.date1, tmp.val1 WHERE tmp.date1 IS NOT NULL
UNION ALL
SELECT tmp.id, tmp.date2, tmp.val2 WHERE tmp.date2 IS NOT NULL
UNION ALL
SELECT tmp.id, tmp.date3, tmp.val3 WHERE tmp.date3 IS NOT NULL
)
AS normalised
在Sql Server 2005之前,您可以将三个单独的查询组合在一起。
SELECT id, date1, val1 FROM yourTable WHERE date1 IS NOT NULL
UNION ALL
SELECT id, date2, val2 FROM yourTable WHERE date2 IS NOT NULL
UNION ALL
SELECT id, date3, val3 FROM yourTable WHERE date3 IS NOT NULL