如何避免 Internal_Function by TO_CHAR IN Oracle

How to avoid Internal_Function by TO_CHAR IN Oracle

我正在使用 Oracle 12C,我有以下代码:

SELECT *
FROM
    (
    SELECT
        *
    FROM
        t.tablea
    WHERE
        name = 'FIS'
) A
LEFT JOIN (
    SELECT
        *
    FROM
        t.tableb
    WHERE
        enabled = 1
) B ON b.id = a.id
       AND TO_CHAR(b.createdate, 'dd-mm-yy hh24:mi') = TO_CHAR(a.createdate, 'dd-mm-yy hh24:mi')

a 和 b createdate 都是时间戳数据类型。

优化器 return internal_function 在 TO_CHAR(b.createdate, 'dd-mm-yy hh24:mi') = TO_CHAR(a.createdate, 'dd-mm-yy hh24:mi') 在执行计划中

如果我这样比较:'AND b.createdate = a.createdate',它将丢失 1000 行,看起来像这样“11-JUN-18 04.48.34.269928000 PM”。如果我将 269928000 更改为 269000000 它将起作用

现在,我不想使用 to_char 来避免 internal_function(必须创建基于函数的索引)

谁能帮帮我?

我什至不认为需要子查询:

SELECT a.*, b.*
FROM t.tablea a
LEFT JOIN t.tableb b
    ON a.id = b.id AND
       TRUNC(b.createdate, 'MI') = TRUNC(a.createdate, 'MI') AND
       b.enabled = 1
WHERE
    a.name = 'FIS'

If I compare like this: AND b.createdate = a.createdate, It will lost 1000 rows that look like this 11-JUN-18 04.48.34.269928000 PM. And If I change 269928000 to 269000000 It will work

您的值似乎包含秒小数部分,并且数据类型为 TIMESTAMP。如果是这样,您可以使用 TRUNC( timestamp_value, 'MI' ) 截断到最近的分钟数。

SELECT *
FROM   t.tablea a
       LEFT OUTER JOIN t.tableb b
       ON (   a.createdate >= TRUNC( b.createdate, 'MI' )
          AND a.createdate <  TRUNC( b.createdate, 'MI' ) + INTERVAL '1' MINUTE
          AND a.id         =  b.id
          AND b.enabled    =  1
          )
WHERE  a.name = 'FIS'

这将消除对两个表之一应用函数的需要(a.createdate 在这种情况下,但您可以交换它们)。