oracle 在sql条件中使用函数的别名

5gfr0r5j  于 2022-11-03  发布在  Oracle
关注(0)|答案(2)|浏览(179)

我有这样的话:

SELECT 
    cansa1.NAME,
    mod(cansa1.PRODUCT_ID, 1000000) prodIdHash

FROM CANSA_TABLE cansa1

INNER JOIN CUSER_TABLE cuser1 ON cansa1.PRODUCT_ID = cuser1.PRODUCT_ID
AND mod(cansa1.PRODUCT_ID, 1000000) = cuser1.PRODUCT_HASH

这个查询是有效的,但是我想替换mod()函数的第二次出现(在内部连接中),以避免执行它两次。我尝试用select子句中的别名替换它,但是不起作用。我可以使用什么方法来使这个查询不重复mod()函数呢?
对不起,我的英语

h43kikqp

h43kikqp1#

不必担心执行两次,SQL引擎将优化查询,并决定是缓存函数值,还是执行两次,最后重写查询,使执行的查询与写入的查询具有不同的结构,因为它已确定这样做会更有效。
如果你真的想重写它,那么:

SELECT c.NAME,
       c.prodIdHash
FROM   (
         SELECT name,
                mod(PRODUCT_ID, 1000000) As prodIdHash
         FROM   CANSA_TABLE
       ) c
       INNER JOIN CUSER_TABLE u
       ON (   c.PRODUCT_ID = u.PRODUCT_ID
          AND c.prodIdHash = u.PRODUCT_HASH )

但是,SQL引擎可能会重写查询并将函数推送到外部作用域,因此您可能需要一个看似无关的筛选条件来具体化内部查询并强制不重写计算:

SELECT c.NAME,
       c.prodIdHash
FROM   (
         SELECT name,
                mod(PRODUCT_ID, 1000000) As prodIdHash
         FROM   CANSA_TABLE
         WHERE  ROWNUM > 0
       ) c
       INNER JOIN CUSER_TABLE u
       ON (   c.PRODUCT_ID = u.PRODUCT_ID
          AND c.prodIdHash = u.PRODUCT_HASH )

然而,这看起来确实像是一个过早优化的案例。在尝试应用可能不需要的优化之前,你应该首先检查是否真的存在问题。

trnvg8h3

trnvg8h32#

您可以使用 * 派生表 *(即FROM子句中的子查询):

SELECT dt.NAME, dt.prodIdHash
FROM
  (SELECT 
       cansa1.NAME,
       mod(cansa1.PRODUCT_ID, 1000000) prodIdHash
   FROM CANSA_TABLE cansa1) dt
INNER JOIN CUSER_TABLE cuser1 ON dt.PRODUCT_ID = cuser1.PRODUCT_ID
  AND dt.prodIdHash = cuser1.PRODUCT_HASH

相关问题