Informix - Date/Time where 子句中的操作

Informix - Date/Time Manipulation in where clause

查看以下查询:

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 to 子句中应用条件从特定时间开始获取数据

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'

我只想了解在我连接 run_date 和 run_time...

的 where 子句本身中进行操作的最佳方法是什么

如果将时间存储为 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。您可以轻松安排将 table 更新为此编码。这有明显的变体,例如:

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