DB2/ODBC 上 SQL 中的日期算术
我正在针对 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 天(显然小于我在 where 子句中请求的 6 天)。
我的第一个想法是 days() 的返回类型可能不是整数,导致比较失败...根据 http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/db2/rbafzmst02.htm,它返回一个bigint。为了安全起见,我将差值转换为整数,但这没有效果。
I'm building a query against a DB2 database, connecting through the IBM Client Access ODBC driver. I want to pull fields that are less than 6 days old, based on the field 'a.ofbkddt'... the problem is that this field is not a date field, but rather a DECIMAL field, formatted as YYYYMMDD.
I was able to break down the decimal field by wrapping it in a call to char(), then using substr() to pull the year, month and day fields. I then formatted this as a date, and called the days() function, which gives a number that I can perform arithmetic on.
Here's an example of the query:
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
This yields the following:
difference mydate
2402 20050402
2025 20060306
...
4 20110917
3 20110918
2 20110919
1 20110920
This is what I expect to see... however when I use the same logic in the where clause of my query:
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
I don't get any results back from my query, even though it's clear that I am getting date differences of as little as 1 day (obviously less than the 6 days that I'm requesting in the where clause).
My first thought was that the return type of days() might not be an integer, causing the comparison to fail... according to the documentation for days() found at http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/db2/rbafzmst02.htm, it returns a bigint. I cast the difference to integer, just to be safe, but this had no effect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你正在倒退。您应该预先计算日期之间的差异,而不是对表中的每个值使用函数(以便您可以将其与日期进行比较)。在每一行上运行该函数会花费您的资源 - 如果您可以在
CURRENT_DATE
之前执行此操作,您会节省很多资源(如果您可以在应用程序中执行此操作,可能会节省更多)代码,但我意识到这可能是不可能的)。毕竟,您的日期是可排序的格式。该查询如下所示:
当针对示例数据表运行时,会产生以下结果:
您可能还想创建一个日历表,并将这些日期添加为其中一列。
You're going about this backwards. Rather than using a function on every single value in the table (so you can compare it to the date), you should pre-compute the difference in the date. It's costing you resources to run the function on every row - you'd save a lot if you could just do it against
CURRENT_DATE
(it'd maybe save you even more if you could do it in your application code, but I realize this might not be possible). Your dates are in a sortable format, after all.The query looks like so:
Which, when run against your sample datatable, yields the following:
You might also want to look into creating a calendar table, and add these dates as one of the columns.
如果您尝试 公用表表达式?
What if you try a common table expression?
您的数据在 a.ofbkddt 中是否有一些空值?也许这会导致 db2 评估小于操作时出现一些有趣的行为。
Does your data have some nulls in a.ofbkddt? Maybe this is causing some funny behaviour in how db2 is evaluating the less than operation.