DB2 / ODBC上的SQL中的日期算术

时间:2011-09-21 16:54:55

标签: sql db2 ibm-midrange

我正在构建一个针对DB2数据库的查询,通过IBM Client Access ODBC驱动程序进行连接。我想根据字段'a.ofbkddt'来提取不到6天的字段...问题是该字段不是日期字段,而是DECIMAL字段,格式为YYYYMMDD。

我能够通过将其包装在对char()的调用中来分解十进制字段,然后使用substr()来提取年,月和日字段。然后我将其格式化为日期,并调用days()函数,它给出了一个我可以执行算术运算的数字。

以下是查询示例:

select
       days( current date) -
       days( substr(char(a.ofbkddt),1,4) concat '-'              -- YYYY-
             concat substr(char(a.ofbkddt),5,2) concat '-'       -- MM-
             concat substr(char(a.ofbkddt),7,2) ) as difference, -- DD
       a.ofbkddt as mydate
from QS36F.ASDF a

这产生以下结果:

difference  mydate
2402        20050402
2025        20060306
...
4           20110917
3           20110918
2           20110919
1           20110920

这是我期望看到的......但是当我在查询的where子句中使用相同的逻辑时:

select
       days( current date) -
       days( substr(char(a.ofbkddt),1,4) concat '-'              -- YYYY-
             concat substr(char(a.ofbkddt),5,2) concat '-'       -- MM-
             concat substr(char(a.ofbkddt),7,2) ) as difference, -- DD
       a.ofbkddt as mydate
from QS36F.ASDF a
where
(
days( current date) -
days( substr(char(a.ofbkddt),1,4) concat '-'         -- YYYY-
      concat substr(char(a.ofbkddt),5,2) concat '-'  -- MM
      concat substr(char(a.ofbkddt),7,2) )           -- DD
) < 6

我的查询没有得到任何结果,即使很明显我的日期差异只有1天(明显少于我要求的6天)在where子句中。

我的第一个想法是,days()的返回类型可能不是整数,导致比较失败...根据http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/db2/rbafzmst02.htm中找到的days()文档,它返回一个bigint。我将差异转换为整数,只是为了安全,但这没有效果。

3 个答案:

答案 0 :(得分:3)

你正在倒退这个。您可以预先计算日期中的差异,而不是对表中的每个值使用函数(因此您可以将其与日期进行比较)。在每一行上运行该功能都会花费你的资源 - 如果你可以对CURRENT_DATE进行操作,你会节省很多(如果你可以在应用程序代码中执行它,它可能会节省更多,但是我意识到这可能是不可能的)。毕竟,您的日期 是可排序的格式。

查询如下:

SELECT ofbkddt as myDate
FROM QS36F.ASDF
WHERE myDate > ((int(substr(char(current_date - 6 days, ISO), 1, 4)) * 10000) +
                (int(substr(char(current_date - 6 days, ISO), 6, 2)) * 100) +
                (int(substr(char(current_date - 6 days, ISO), 9, 2))))

当针对您的示例数据表运行时,会产生以下结果:

myDate
=============
20110917
20110918
20110919
20110920

您可能还想查看创建日历表,并将这些日期添加为其中一列。

答案 1 :(得分:1)

如果您尝试common table expression怎么办?

WITH A AS
(
    select
       days( current date) -
       days( substr(char(a.ofbkddt),1,4) concat '-'              -- YYYY-
             concat substr(char(a.ofbkddt),5,2) concat '-'       -- MM-
             concat substr(char(a.ofbkddt),7,2) ) as difference, -- DD
       a.ofbkddt as mydate
    from QS36F.ASDF a
)
SELECT
    *
FROM
    a
WHERE
    difference < 6

答案 2 :(得分:0)

你的数据在a.ofbkddt中是否有一些空值?也许这会导致db2如何评估小于操作的一些有趣的行为。