我目前有一个通过Union [代码块1]设置的查询来收集数据。它可以正常工作,但是要重复很多次效率很低
在DB2中是否可以将其转换为while循环?
我试图在[代码块2]中编写一个while循环,但是在DB2中不起作用。
我在Code_block_2中不断收到语法错误
在代码块2中,我想在开始日期和结束日期变量中加1,以便下一次查询将以新的时间段(存储为整数)运行,例如,第一次是在201601和201701之间,第二次是在201602和201702之间。我尝试将end_dt设置为与每行数据一起打印
union方法有效,但是我不得不多次编写相同的代码块。循环会更有效
[代码块1-联合(Works)]
select
1 as a.period,
a.name,
a.date
from
data_table
where
month between 201601 and 201701
union
select
1 as period,
a.name,
a.date
from
data_table a
where
a.month between 201602 and 201702 -- this is changing in a consistent pattern
union
select
1 as period,
a.name,
a.date
from
data_table a
where
a.month between 201603 and 201703
[代码块2-尝试循环]
Begin atomic
declare @end_dt integer default 201701;
declare @start_dt integer default 201601;
while @end_dt < 201712 do
--statement
select
@end_dt as period,
a.name,
a.date
from
data_table a
where
month between @start_dt and @end_dt;
-- add + 1 to variables
set @end_dt = @end_dt +1;
set @start_dt = @start_dt +1;
end while;
end;
这是示例数据集
(在数据库中)
名称-日期 简-2016年5月2日
吉姆-2016年6月3日
Zack-2016年1月1日
吉尔-2016年5月1日
乔-2016年1月1日
詹姆斯-2016年4月1日
佐伊-2016年2月2日
输出(预期,代码块1的结果。)
期间-名称-日期
201701-简-2016/5/2
201701-吉姆-2016年6月3日
201701-Zack-2016年1月1日
201701-吉尔-2016年5月1日
201701-乔-2016年1月1日
201701-詹姆斯-2016年4月1日
201701-佐伊-2016年2月2日
201702-简-2016/5/2
201702-吉姆-2016年6月3日
201702-吉尔-2016年5月1日
201702-詹姆斯-2016年4月1日
201702-佐伊-2016年2月2日
-请注意,2016年1月1日的日期如何在201702年的时间段中滴答作响
我不太确定DB2的版本,但这与
适用于Linux Unix和Windows 10.5的DB2
和z / OS
答案 0 :(得分:1)
按原样运行以下查询。
这是您要查找的“虚拟”表range
吗?
with t(n, m) as (
select 1, date(to_date(201601, 'YYYYMM')) from sysibm.sysdummy1
union all
select n+1, m + 1 month
from t
where n<11
)
, range (start, end) as (
select year(m)*100+month(m) as start, year(m + 1 year)*100+month(m + 1 year) as end
from t
)
select start, end
from range r;
如果是,那么您可以在range
条件下将此data_table
与您的a.month between r.start and r.end
联接起来,以获得您提供的结果。
答案 1 :(得分:0)
系统上是否有日期暗/日历表?
如果没有,我只是放入一个值表。可以将其更改为所需的任何内容。它只需要具有所需时间范围内的YYYYMM日期值列表。
select
dates.period,
a.name,
a.date
from
table( values
(201701)
,(201702)
,(201703)
,(201704)
,(201705)
,(201706)
,(201707)
,(201708)
,(201709)
,(201710)
,(201711)
,(201712)
) date(period)
join
data_table
on a.month between (date.period - 100) and date.period