Oracle兼容-语法-DATETIME INTERVAL加减运算


1. 语法

  1. DATETIME_expr [+|-] INTERVAL expr type

2. 定义和用法

GreatSQL支持对 DATETIME 类型数据进行 INTERVAL 加减运算。

若位于另一端的表达式是一个日期或日期时间值,则 INTERVAL expr type 只允许在 + 操作符的两端。对于 操作符,INTERVAL expr type 只允许在其右端,因为从一个时间间隔中提取一个日期或日期时间值无意义。

  1. 在Oracle中 INTERVAL 可作为字段类型建表等操作中使用,但GreatSQL不存在该类型,因此目前不支持 INTERVAL 作为字段类型使用。

  2. 目前支持范围仅为语法中日期值或时间值与 INTERVAL 加减操作,鉴于目前 GreatSQLINTERVAL 语法实现方式,在Oracle语法中 INTERVAL 内对精度的设置例如:YEAR(3),目前在兼容语法中精度值不具有实际使用意义。

3. 示例

说明: 目前GreatSQL中SYSDATENOWSYSTIMESTAMP 等时间类型与Oracle返回时间值存在差异,因此下面示例中以固定年月时间演示 INTERVAL 与时间值加减语法操作后在 GreatSQL 中返回与Oracle返回做对比。

    1. '2000-01-01 00:00:00' + INTERVAL '80' SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '80' SECOND FROM DUAL;
  3. +----------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '80' SECOND |
  5. +----------------------------------------------+
  6. | 2000-01-01 00:01:20 |
  7. +----------------------------------------------+
  8. -- Oracle
  9. -- 先统一设置日期格式
  10. SQL> ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS';
  11. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '80' SECOND FROM DUAL;
  12. TO_DATE('2000-01-01 00:00:00') + INTERVAL '80' SECOND
  13. -------------------
  14. 2000-01-01 00:01:20
    1. '2000-01-01 00:00:00' - INTERVAL '80' SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '80' SECOND FROM DUAL;
  3. +----------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '80' SECOND |
  5. +----------------------------------------------+
  6. | 1999-12-31 23:58:40 |
  7. +----------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '80' SECOND FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '80' SECOND
  11. -------------------
  12. 1999-12-31 23:58:40
    1. '2000-01-01 00:00:00' + INTERVAL '80' SECOND(2)
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '80' SECOND(2) FROM DUAL;
  3. +-------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '80' SECOND(2) |
  5. +-------------------------------------------------+
  6. | 2000-01-01 00:01:20 |
  7. +-------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '80' SECOND(2) FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '80' SECOND(2)
  11. -------------------
  12. 2000-01-01 00:01:20
    1. '2000-01-01 00:00:00' - INTERVAL '80' SECOND(2)
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '80' SECOND(2) FROM DUAL;
  3. +-------------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '80' SECOND(2) |
  5. +-------------------------------------------------+
  6. | 1999-12-31 23:58:40 |
  7. +-------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '80' SECOND(2) FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '80' SECOND(2)
  11. -------------------
  12. 1999-12-31 23:58:40
    1. '2000-01-01 00:00:00' + INTERVAL '80' MINUTE
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '80' MINUTE FROM DUAL;
  3. +-----------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '80' MINUTE |
  5. +-----------------------------------------------+
  6. | 2000-01-01 01:20:00 |
  7. +-----------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '80' MINUTE FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '80' MINUTE
  11. -------------------
  12. 2000-01-01 01:20:00
    1. '2000-01-01 00:00:00' - INTERVAL '80' MINUTE
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '80' MINUTE FROM DUAL;
  3. +-----------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '80' MINUTE |
  5. +-----------------------------------------------+
  6. | 1999-12-31 22:40:00 |
  7. +-----------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '80' MINUTE FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '80' MINUTE
  11. -------------------
  12. 1999-12-31 22:40:00
    1. '2000-01-01 00:00:00' + INTERVAL '15:30' MINUTE TO SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '15:30' MINUTE TO SECOND FROM DUAL;
  3. +------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '15:30' MINUTE TO SECOND |
  5. +------------------------------------------------------------+
  6. | 2000-01-01 00:15:30 |
  7. +------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '15:30' MINUTE TO SECOND FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '15:30' MINUTE TO SECOND
  11. -------------------
  12. 2000-01-01 00:15:30
    1. '2000-01-01 00:00:00' - INTERVAL '15:30' MINUTE TO SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '15:30' MINUTE TO SECOND FROM DUAL;
  3. +------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '15:30' MINUTE TO SECOND |
  5. +------------------------------------------------------------+
  6. | 1999-12-31 23:44:30 |
  7. +------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '15:30' MINUTE TO SECOND FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '15:30' MINUTE TO SECOND
  11. -------------------
  12. 1999-12-31 23:44:30
    1. '2000-01-01 00:00:00' + INTERVAL '09:08:07' HOUR to SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '09:08:07' HOUR to SECOND FROM DUAL;
  3. +--------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '09:08:07' HOUR to SECOND |
  5. +--------------------------------------------------------------+
  6. | 2000-01-01 09:08:07 |
  7. +--------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '09:08:07' HOUR to SECOND FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '09:08:07' HOUR to SECOND
  11. -------------------
  12. 2000-01-01 09:08:07
    1. '2000-01-01 00:00:00' - INTERVAL '09:08:07' HOUR to SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '09:08:07' HOUR to SECOND FROM DUAL;
  3. +--------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '09:08:07' HOUR to SECOND |
  5. +--------------------------------------------------------------+
  6. | 1999-12-31 14:51:53 |
  7. +--------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '09:08:07' HOUR to SECOND FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '09:08:07' HOUR to SECOND
  11. -------------------
  12. 1999-12-31 14:51:53

注意: GreatSQL中若 INTERVAL 后数据与 type 关键字指定不一致时返回NULL。

    1. '2000-01-01 00:00:00' + INTERVAL '09:08:07.666666' HOUR TO SECOND(7)
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '09:08:07.666666' HOUR TO SECOND(7) FROM DUAL;
  3. +-----------------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '09:08:07.666666' HOUR TO SECOND(7) |
  5. +-----------------------------------------------------------------------+
  6. | NULL |
  7. +-----------------------------------------------------------------------+
  8. -- 可使用GreatSQL兼容语法 HOUR TO MICROSECOND 替换
  9. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '09:08:07.666666' HOUR TO MICROSECOND(7) FROM DUAL;
  10. +-----------------------------------------------------------------------+
  11. | '2000-01-01 00:00:00' + INTERVAL '09:08:07.666666' HOUR TO MICROSECOND(7) |
  12. +----------------------------------------------------------------------+
  13. | 2000-01-01 09:08:07.666666 |
  14. +----------------------------------------------------------------------+
  15. -- Oracle
  16. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '09:08:07.666666' HOUR TO SECOND(7) FROM DUAL;
  17. TO_DATE('2000-01-01 00:00:00') + INTERVAL '09:08:07.666666' HOUR TO SECOND(7)
  18. -------------------
  19. 2000-01-01 09:08:07

注意: 在GreatSQL中若 INTERVAL 运算后数据与 type 关键字指定不一致时返回NULL。

    1. '2000-01-01 00:00:00' - INTERVAL '09:08:07.666666' HOUR TO SECOND(7)
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '09:08:07.666666' HOUR TO SECOND(7) FROM DUAL;
  3. +-----------------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '09:08:07.666666' HOUR TO SECOND(7) |
  5. +-----------------------------------------------------------------------+
  6. | NULL |
  7. +-----------------------------------------------------------------------+
  8. -- 可使用GreatSQL兼容语法 HOUR TO MICROSECOND 替换
  9. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '09:08:07.666666' HOUR TO MICROSECOND(7) FROM DUAL;
  10. +----------------------------------------------------------------------------+
  11. | '2000-01-01 00:00:00' - INTERVAL '09:08:07.666666' HOUR TO MICROSECOND(7) |
  12. +----------------------------------------------------------------------------+
  13. | 1999-12-31 14:51:52.333334 |
  14. +----------------------------------------------------------------------------+
  15. -- Oracle
  16. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '09:08:07.666666' HOUR TO SECOND(7) FROM DUAL;
  17. TO_DATE('2000-01-01 00:00:00') - INTERVAL '09:08:07.666666' HOUR TO SECOND(7)
  18. -------------------
  19. 1999-12-31 14:51:52
    1. '2000-01-01 00:00:00' + INTERVAL '2 1:3:4' DAY to SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '2 1:3:4' DAY to SECOND FROM DUAL;
  3. +-----------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '2 1:3:4' DAY to SECOND |
  5. +-----------------------------------------------------------+
  6. | 2000-01-03 01:03:04 |
  7. +-----------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '2 1:3:4' DAY to SECOND FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '2 1:3:4' DAY to SECOND
  11. -------------------
  12. 2000-01-03 01:03:04
    1. '2000-01-01 00:00:00' - INTERVAL '2 1:3:4' DAY to SECOND
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '2 1:3:4' DAY to SECOND FROM DUAL;
  3. +-----------------------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '2 1:3:4' DAY to SECOND |
  5. +-----------------------------------------------------------+
  6. | 1999-12-29 22:56:56 |
  7. +-----------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '2 1:3:4' DAY to SECOND FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '2 1:3:4' DAY to SECOND
  11. -------------------
  12. 1999-12-29 22:56:56
    1. '2000-01-01 00:00:00' + INTERVAL '11 10:09' DAY TO MINUTE
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '11 10:09' DAY TO MINUTE FROM DUAL;
  3. +------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '11 10:09' DAY TO MINUTE |
  5. +------------------------------------------------------------+
  6. | 2000-01-12 10:09:00 |
  7. +------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '11 10:09' DAY TO MINUTE FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '11 10:09' DAY TO MINUTE
  11. -------------------
  12. 2000-01-12 10:09:00
    1. '2000-01-01 00:00:00' - INTERVAL '11 10:09' DAY TO MINUTE
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '11 10:09' DAY TO MINUTE FROM DUAL;
  3. +------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '11 10:09' DAY TO MINUTE |
  5. +------------------------------------------------------------+
  6. | 1999-12-20 13:51:00 |
  7. +------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '11 10:09' DAY TO MINUTE FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '11 10:09' DAY TO MINUTE
  11. -------------------
  12. 1999-12-20 13:51:00
    1. '2000-01-01 00:00:00' + INTERVAL '100 10' DAY(3) TO HOUR
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '100 10' DAY(3) TO HOUR FROM DUAL;
  3. +-----------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '100 10' DAY(3) TO HOUR |
  5. +-----------------------------------------------------------+
  6. | 2000-04-11 10:00:00 |
  7. +-----------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '100 10' DAY(3) TO HOUR FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '100 10' DAY(3) TO HOUR
  11. -------------------
  12. 2000-04-11 10:00:00
    1. '2000-01-01 00:00:00' - INTERVAL '100 10' DAY(3) TO HOUR
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '100 10' DAY(3) TO HOUR FROM DUAL;
  3. +-----------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '100 10' DAY(3) TO HOUR |
  5. +-----------------------------------------------------------+
  6. | 1999-09-22 14:00:00 |
  7. +-----------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '100 10' DAY(3) TO HOUR FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '100 10' DAY(3) TO HOUR
  11. -------------------
  12. 1999-09-22 14:00:00
    1. '2000-01-01 00:00:00' + INTERVAL '123-2' YEAR(3) TO MONTH
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' + INTERVAL '123-2' YEAR(3) TO MONTH FROM DUAL;
  3. +------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' + INTERVAL '123-2' YEAR(3) TO MONTH |
  5. +------------------------------------------------------------+
  6. | 2123-03-01 00:00:00 |
  7. +------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') + INTERVAL '123-2' YEAR(3) TO MONTH FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') + INTERVAL '123-2' YEAR(3) TO MONTH
  11. -------------------
  12. 2123-03-01 00:00:00
    1. '2000-01-01 00:00:00' - INTERVAL '123-2' YEAR(3) TO MONTH
  1. -- GreatSQL
  2. greatsql> SELECT '2000-01-01 00:00:00' - INTERVAL '123-2' YEAR(3) TO MONTH FROM DUAL;
  3. +------------------------------------------------------------+
  4. | '2000-01-01 00:00:00' - INTERVAL '123-2' YEAR(3) TO MONTH |
  5. +------------------------------------------------------------+
  6. | 1876-11-01 00:00:00 |
  7. +------------------------------------------------------------+
  8. -- Oracle
  9. SQL> SELECT TO_DATE('2000-01-01 00:00:00') - INTERVAL '123-2' YEAR(3) TO MONTH FROM DUAL;
  10. TO_DATE('2000-01-01 00:00:00') - INTERVAL '123-2' YEAR(3) TO MONTH
  11. -------------------
  12. 1876-11-01 00:00:00
    1. '0001-01-01 00:00:00' - INTERVAL '123-2' YEAR(3) TO MONTH

注意:

    1. 对于极限年份的处理GreatSQL与Oracle不同。
    1. 当输入时间或日期值不满足与 INTERVAL 格式内容减运算时,GreatSQL返回NULL。
  1. -- GreatSQL
  2. greatsql> SELECT '0001-01-01 00:00:00' - INTERVAL '123-2' YEAR(3) TO MONTH FROM DUAL;
  3. +-------------------------------------------------------------+
  4. | '0001-01-01 00:00:00' - INTERVAL '123-2' YEAR(3) TO MONTH |
  5. +-------------------------------------------------------------+
  6. | NULL |
  7. +-------------------------------------------------------------+
  8. SQL> SELECT TO_DATE('0001-01-02 00:00:00') - INTERVAL '123-2' YEAR(3) TO MONTH FROM DUAL;
  9. TO_DATE('0001-01-02 00:00:00') - INTERVAL '123-2' YEAR(3) TO MONTH
  10. -------------------
  11. 0123-11-02 00:00:00
    1. '0001-01-01 00:00:00' - INTERVAL '100 10' DAY(3) TO HOUR
  1. -- GreatSQL
  2. greatsql> SELECT '0001-01-01 00:00:00' - INTERVAL '100 10' DAY(3) TO HOUR FROM DUAL;
  3. +-----------------------------------------------------------+
  4. | '0001-01-01 00:00:00' - INTERVAL '100 10' DAY(3) TO HOUR |
  5. +-----------------------------------------------------------+
  6. | 0000-00-00 14:00:00 |
  7. +-----------------------------------------------------------+
  8. SQL> SELECT TO_DATE('0001-01 00:00:00') - INTERVAL '100 10' DAY(3) TO HOUR FROM DUAL;
  9. TO_DATE('0001-01-01 00:00:00') - INTERVAL '100 10' DAY(3) TO HOUR
  10. -------------------
  11. 0000-09-22 14:00:00

问题反馈

联系我们

扫码关注微信公众号

greatsql-wx