Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将日期拆分为多个字段时按日期范围筛选_Sql_Db2 - Fatal编程技术网

Sql 将日期拆分为多个字段时按日期范围筛选

Sql 将日期拆分为多个字段时按日期范围筛选,sql,db2,Sql,Db2,我正在使用一个数据库,该数据库将日期作为整数(模拟字段名)存储在多个字段中: 世纪:CC01:20 年份:YR01:13 月份:MO01:7 日期:DY01:22 我可以这样表述一个日期:date((CC01*100+YR01)| |'-'| | MO01 | |'-'| | DY01) 问题是当我需要过滤一系列日期时。例如,如果我想选择过去的90天,我可以这样写 WHERE DATE((CC01*100+YR01)| |'-| | | MO01 | |'-| | | DY01)>=当前日期

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

  • 世纪:CC01:20
  • 年份:YR01:13
  • 月份:MO01:7
  • 日期:DY01:22
我可以这样表述一个日期:
date((CC01*100+YR01)| |'-'| | MO01 | |'-'| | DY01)

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

WHERE DATE((CC01*100+YR01)| |'-| | | MO01 | |'-| | | DY01)>=当前日期-90天

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

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

其中CC01=20,YR01>=右(年(当前日期-7天),2)和MO01>=月(当前日期-7天),DY01>=天(当前日期-7天)


这只会起作用,因为回溯7天会使我们保持当前月份和年份。我也不希望有大量的and和OR(如果可能)。

您有权修改DB模式吗? 如果是这样,您可以考虑日期的“生成列”:


您有权修改数据库模式吗? 如果是这样,您可以考虑日期的“生成列”:


您要查询的日期范围长度是否有限制? 对于短范围,您可以生成详细的动态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)

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

您将查询的日期范围长度是否有限制? 对于短范围,您可以生成详细的动态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)

你必须分析一下,看看较长的查询是否能弥补较快的查找速度(我的直觉说,跨越数亿条记录的函数调用会较慢,尽管直觉永远不可信)。

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

        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)
            )
CC01=20
及
YR01>=右侧(年份(当前日期-220天),2)
而不是
(
YR01=右侧(年份(当前日期-220天),2)
及
MO01=月份(当前日期-220天)
及
DY01<天(当前日期-220天)
)
而不是
(
YR01=右侧(年份(当前日期-220天),2)
及
MO01<月份(当前日期-220天)
)

我相信我已经找到了解决办法

        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)
            )
CC01=20
及
YR01>=右侧(年份(当前日期-220天),2)
而不是
(
YR01=右侧(年份(当前日期-220天),2)
及
MO01=月份(当前日期-220天)
及
DY01<天(当前日期-220天)
)
而不是
(
YR01=右侧(年份(当前日期-220天),2)
及
MO01<月份(当前日期-220天)
)

定义要转换为日期的函数

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。

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

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。

将其作为额外列选择,这样您只需定义一次?并在where子句中使用该列。也许将日期转换为UNIX时间戳(整数)更容易些,将
限制在val1和val2之间我遇到的问题是表中有数亿条记录。表值上的任何函数都将永远需要处理,并且会占用太多的临时空间。您已经提供了公式。我只有对此数据源的读取权限,将其选择为额外列,因此您只需定义一次?并在where子句中使用该列。也许将日期转换为UNIX时间戳(整数)更容易些,将
限制在val1和val2之间我遇到的问题是表中有数亿条记录。表值上的任何函数都将永远需要处理,并且会占用太多的临时空间。您已经提供了公式。我只有对此数据源的读取权限。很遗憾,没有,访问权限是只读的。在我看来,任何解决方案都必须发生在WHERE语句中。不幸的是,没有,访问是只读的。在我看来,任何解决方案都必须在WHERE语句中进行。不幸的是,日期范围必须是动态的。如果您的日期范围限制在几百个,而您的DB表只有几亿个,那么最好是按照请求的日期而不是按DB行进行额外处理。是的,我的意思是在数据库中调用的任何代码中生成SQL查询,或者添加一个包含两个日期并生成SQL字符串的存储过程,如果所有这些都需要在DBa存储过程中生成,就像这样,除了在while循环中,您可以添加一个新的或。。。子句到字符串不幸的是,日期范围需要是动态的。如果您的日期范围限制在几百个,而您的DB表只有几亿个,那么按照请求的日期而不是按DB行进行额外处理肯定会更好。是的,我的意思是在数据库中调用的任何代码中生成SQL查询,或者添加一个包含两个日期并生成SQL字符串的存储过程,如果所有这些都需要在DBa存储过程中生成,就像这样,除了在while循环中,您可以添加一个新的或。。。