0

我正在使用一个将多个字段中的日期存储为整数(模拟字段名称)的数据库:

  • 世纪:CC01:20
  • 年份:YR01:13
  • 月:MO01:7
  • 日:DY01:22

我可以这样制定日期:DATE((CC01 * 100 + YR01) || '-' || MO01 || '-' || DY01)

问题是当我需要过滤一系列日期时。例如,如果我想选择过去 90 天,我可以这样写……

WHERE DATE((CC01 * 100 + YR01) || '-' || MO01 || '-' || DY01) >= CURRENT DATE - 90 DAYS

这里的问题是性能。我正在寻找一种有效的方法来编写此公式,以将函数限制在等式的右侧。

这是一个适用于今天日期的示例(我不需要担心世纪,我省略了一些细节):

WHERE CC01 = 20 AND YR01 >= RIGHT(YEAR(CURRENT DATE - 7 DAYS),2) AND MO01 >= MONTH(CURRENT DATE - 7 DAYS) AND DY01 >= DAY(CURRENT DATE - 7 DAYS)

这只有效,因为返回 7 天让我们保持在当前月份和年份。我也不希望有大量的 AND 和 OR(如果可能的话)。

4

4 回答 4

1

您要查询的日期范围的长度是否有限制?对于短距离,您可以生成一个详细的动态 SQL,例如:

WHERE
    (CC01 = 20 AND YR01 = 07 AND MO01 = 02 AND DY01 = 01)
 OR (CC01 = 20 AND YR01 = 07 AND MO01 = 03 AND DY01 = 04)
 OR (CC01 = 20 AND YR01 = 07 AND MO01 = 04 AND DY01 = 03)

您必须进行分析以查看更长的查询是否补偿了更快的查找(我的直觉说跨数亿条记录的函数调用会更慢,尽管直觉永远不可信)。

于 2013-07-22T14:43:29.323 回答
1

我相信我可能已经找到了解决方案。

        CC01 = 20
        AND
        YR01 >= RIGHT(YEAR(CURRENT DATE - 220 DAYS),2)
        AND NOT
            (
            YR01 = RIGHT(YEAR(CURRENT DATE - 220 DAYS),2)
            AND
            MO01 = MONTH(CURRENT DATE - 220 DAYS)
            AND
            DY01 < DAY(CURRENT DATE - 220 DAYS)
            )
        AND NOT
            (
            YR01 = RIGHT(YEAR(CURRENT DATE - 220 DAYS),2)
            AND
            MO01 < MONTH(CURRENT DATE - 220 DAYS)
            )
于 2013-07-22T14:51:45.310 回答
1

您是否有权修改数据库架构?如果是这样,您可以考虑为日期创建一个“生成的列”:

https://www.ibm.com/developerworks/community/blogs/SQLTips4DB2LUW/entry/expression_generated_columns?lang=en

于 2013-07-22T14:33:27.977 回答
0

定义一个转换为日期的函数

CREATE FUNCTION parts2date (cc int, yy int, mm int,  dd int ) returns date
    LANGUAGE SQL
    CONTAINS SQL
    DETERMINISTIC
  BEGIN
    RETURN DATE( RIGHT(DIGITS(cc),2)||RIGHT(DIGITS(yy),w)||'-'
               ||RIGHT(DIGITS(mm),2)||'-'||RIGHT(DIGITS(dd),2) );
  END;

您可以添加一个条件处理程序,以在错误时返回 null。

于 2013-07-23T11:14:51.380 回答