Informix - where子句中的日期/时间操作

时间:2017-06-13 15:31:44

标签: informix

见下面的查询:

DROP TABLE IF EXISTS rd_rt_date_integer;
CREATE TABLE rd_rt_date_integer
(
    run_date    DATE NOT NULL,
    run_time    INTEGER NOT NULL
                CHECK (run_time >= 0 AND run_time < 2400 AND MOD(run_time, 100) < 60),
    PRIMARY KEY(run_date, run_time)
);

INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 0);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 100);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 200);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 300);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 400);

SELECT run_date, run_time,
       EXTEND(run_date, YEAR TO MINUTE) +
       MOD(run_time, 100) UNITS MINUTE +
       (run_time / 100) UNITS HOUR AS run_date_time
  FROM rd_rt_date_integer;

问题:如何在条件的where where子句中应用条件从某个时间开始获取数据

SELECT run_date, run_time,
       EXTEND(run_date, YEAR TO MINUTE) +
       MOD(run_time, 100) UNITS MINUTE +
       (run_time / 100) UNITS HOUR AS run_date_time
  FROM rd_rt_date_integer
where EXTEND(run_date, YEAR TO MINUTE) +
       MOD(run_time, 100) UNITS MINUTE +
       (run_time / 100) UNITS HOUR >='2017-05-22 02:00'

我只是想了解什么是在where子句本身进行操作的最佳方法,其中我连接了run_date和run_time ......

1 个答案:

答案 0 :(得分:1)

如果将时间存储为INTERVAL HOUR TO MINUTE,会更简单。 然后,您可以使用以下方法简化第一个查询:

DROP TABLE IF EXISTS rd_rt_date_integer;
CREATE TABLE rd_rt_date_integer
(
    run_date    DATE NOT NULL,
    run_time    INTERVAL HOUR TO MINUTE NOT NULL
                CHECK (run_time >= INTERVAL(0:0) HOUR TO MINUTE AND run_time < INTERVAL(24:00) HOUR TO MINUTE),
    PRIMARY KEY(run_date, run_time)
);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', '0:0');
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', '1:00');
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', '2:00');
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', '3:00');
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', '4:00');

SELECT run_date, run_time,
       EXTEND(run_date, YEAR TO MINUTE) + run_time AS run_date_time
  FROM rd_rt_date_integer;

但是,你可能有理由使用整数run_time,即使这会让时间计算变得很糟糕。

此代码有效 - 我建议使用存储过程:

DROP TABLE IF EXISTS rd_rt_date_integer;
CREATE TABLE rd_rt_date_integer
(
    run_date    DATE NOT NULL,
    run_time    INTEGER NOT NULL
                CHECK (run_time >= 0 AND run_time < 2400 AND MOD(run_time, 100) < 60),
    PRIMARY KEY(run_date, run_time)
);

INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 0);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 100);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 200);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 300);
INSERT INTO rd_rt_date_integer VALUES('2017-05-22', 400);

SELECT run_date, run_time,
       EXTEND(run_date, YEAR TO MINUTE) +
       MOD(run_time, 100) UNITS MINUTE +
       (run_time / 100) UNITS HOUR AS run_date_time
  FROM rd_rt_date_integer
 WHERE EXTEND(run_date, YEAR TO MINUTE) +
       MOD(run_time, 100) UNITS MINUTE +
       (run_time / 100) UNITS HOUR >= DATETIME(2017-05-22 02:00) YEAR TO MINUTE
    OR EXTEND(run_date, YEAR TO MINUTE) +
       MOD(run_time, 100) UNITS MINUTE +
       (run_time / 100) UNITS HOUR >= EXTEND('2017-05-22 02:00', YEAR TO MINUTE)
;

DROP FUNCTION IF EXISTS run_date_time;

CREATE FUNCTION run_date_time(rd DATE, rt INTEGER)
    RETURNING DATETIME YEAR TO MINUTE;
    DEFINE rv DATETIME YEAR TO MINUTE;
    LET rv = EXTEND(rd, YEAR TO MINUTE) + MOD(rt, 100) UNITS MINUTE  + (rt / 100) UNITS HOUR;
    RETURN rv;
END FUNCTION;

SELECT run_date, run_time,
       run_date_time(run_date, run_time) AS run_date_time
  FROM rd_rt_date_integer
 WHERE run_date_time(run_date, run_time) >= DATETIME(2017-05-22 02:00) YEAR TO MINUTE
    OR run_date_time(run_date, run_time) >= EXTEND('2017-05-22 02:00', YEAR TO MINUTE)
    OR run_date_time(run_date, run_time) >= run_date_time('2017-05-22', 200)
;

后面的SELECT语句中的OR条件显示了写条件的不同命名法。它们相同,只需要其中一个条件;其他的都是多余的。

如果您只是将午夜时间的分钟存储在run_time列中,而不是将其编码为100 * hours + minutes,那么您可以编写如下表达式:

DATETIME(2017-06-12 00:00) YEAR TO MINUTE + 245 UNITS MINUTE

该表达式的计算结果为2017-06-12 04:05。您可以轻松安排将表更新为此编码。这有明显的变体,例如:

EXTEND(TODAY, YEAR TO MINUTE) + 245 UNITS MINUTE
EXTEND(run_date, YEAR TO MINUTE) + run_time UNITS MINUTE