【发布时间】:2018-09-12 11:48:34
【问题描述】:
我有一个类似的表(SAS SQL 中的代码,但我可以转换来自 SQLServer 引擎的回复,因为我有一些经验):
proc sql;
create table work.temp1
(date_from num informat=date7. format=date7.,
date_to num informat=date7. format=date7.,
some_number num);
insert into work.temp1
values('15MAY2018'd,'26JUL18'd, 10);
QUIT;
结果:
我想将它转换为(通过一些巧妙的连接,可能还有一些带有日期和月份的临时表):
proc sql;
create table work.temp2
(date_from num informat=date7. format=date7.,
date_to num informat=date7. format=date7.,
some_number num);
insert into work.temp2
values('15MAY2018'd,'31MAY18'd, 10)
values('1JUN2018'd,'30JUN18'd, 10)
values('1JUL2018'd,'26JUL18'd, 10);
QUIT;
结果:
所有其他列都应重复。从和到的日期始终在一个日历日期中,但每一行可以在不同的年份(2016-2020)。
[编辑]:
Tom 解决方案看起来不错,但在我使用之前,我正在尝试开发 SQL 解决方案。
我在我的数据库中添加了一个“日历”表,它看起来像: 名称:work.calendar
现在我正在考虑的加入是这样的:
SELECT t1.*
FROM work.temp1 t1 INNER JOIN
work.calendar t2 ON t1.date_from >= t2.month_FROM AND t1.date_to <= month_TO
但它显然不起作用。
【问题讨论】:
-
为此的基本技术是建立一个人工日期列表,代表本月的第一天,并将您的实际数据加入其中,人工日期在实际数据日期之间,这样您的人工 JUN 和 JUL 与您的实际数据交叉。人工日期可以通过多种方式形成,通常涉及递增计数器和 DATEADD 样式操作,例如,如果您需要 1000 个日期,请选择至少有 1000 行的表并从中选择一个行号..跨度>
-
或者,如果您有一个数字/日期表(许多 DBA 为这样的事情创建一个),那么只需以一种导致数据行重复的方式加入该表(
artificialdates JOIN actualdates ON artificildates.date BETWEEN actual.from and actual.to然后选择日期以 case 表示 (when actualenddate < artificialdate+1month, actualdate, else artificialdate+1month) -
用 SQL 做起来并不容易,但用普通的 SAS 代码做起来并不难。
标签: sql sql-server sas proc-sql