我正在尝试创建一个查询,以便生成特定起点和终点之间的日期范围。
我有以下内容:
WITH DATE_RANGE(DATE_FOR_SHIFT)
AS (SELECT DATE('2015-04-01')
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT DATE_FOR_SHIFT + 1 DAY
FROM DATE_RANGE
WHERE DATE_FOR_SHIFT <= @END)
SELECT DATE_FOR_SHIFT
FROM DATE_RANGE;
输出(假设@END
等于2015-05-01
):
2015-04-01
2015-04-02
2015-04-03
2015-04-04
...
2015-05-01
输出正确,但我希望能够根据提供的参数更改起点和点,而不是必须重写查询或者有一个易于SQL注入的查询。
如何重写此查询以实现此目的?
答案 0 :(得分:2)
您的SELECT很好,除了硬编码的开始日期。
我认为您缺少的是将其包装在存储过程或用户定义的表函数(UDTF)中。假设您想要将日期范围加入其他表,我建议使用UDTF。
create function date_range (@str date, @end date)
returns table (date_for_shift date)
language SQL
reads SQL data
return
WITH DATE_RANGE(DATE_FOR_SHIFT)
AS (SELECT @str
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT DATE_FOR_SHIFT + 1 DAY
FROM DATE_RANGE
WHERE DATE_FOR_SHIFT <= @END)
SELECT DATE_FOR_SHIFT
FROM DATE_RANGE;
那你就叫它......
select * from table(date_range(date('2015-04-01'),date('2015-05-01'))) as tbl;
但是,不要动态生成这个日期范围....考虑简单地创建一个日历(又名日期)表。基本上只是一张桌子,日期从1900-01-01到2500-12-31 ......或者你喜欢什么。在日期列旁边,您可以添加许多其他列,例如business_day,holiday等等,这些列可以让生活更轻松。
谷歌“SQL日历表”有很多例子。
答案 1 :(得分:1)
在perl中玩这个有点让我:
#!/opt/myperl/5.20.2/bin/perl
use 5.10.0;
use DBI;
use DBD::DB2;
use Data::Dump;
my $sql = <<EOSQL;
WITH DATE_RANGE(DATE_FOR_SHIFT)
AS (SELECT CAST(? AS DATE)
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT DATE_FOR_SHIFT + 1 DAY
FROM DATE_RANGE
WHERE DATE_FOR_SHIFT < CAST(? AS DATE))
SELECT DATE_FOR_SHIFT
FROM DATE_RANGE;
EOSQL
my $dbh = DBI->connect('dbi:DB2:sample');
my $sth = $dbh->prepare_cached($sql);
$sth->execute('2015-04-01','2015-05-01');
my $rc = $sth->fetchall_arrayref();
dd($rc);
这确实在准备期间出现错误(“递归公用表表达式”MYSCHEMA.DATE_RANGE“可能包含无限循环”)我还没想到,但是fetch确实有效,最终返回从04开始-01至05-01。希望您可以将其移植到您想要的语言。